数据转换工具采用cesiumlab1.5.17版本,转换后的3dTiles加载显示比较简单,通过Cesium.Cesium3DTileset接口指定url即可,3dTiles文件可与js前端代码放置一起,也可是远程服务器上的地址。如下:
1 //故宫 2 var palaceTileset = new Cesium.Cesium3DTileset({ 3 url: './TestData/output/DAEPalace/tileset.json' 4 //或者url: 'http://ip:port/www/DAEPalace/tileset.json' 5 }) 6 viewer.scene.primitives.add(palaceTileset);
通过上述代码加载的三维模型位置和高度可能不符合预期,需要进行调整,调整代码如下:
1 var height = -30; //根据地形设置调整高度 2 palaceTileset.readyPromise.then(function(argument) { 3 //贴地显示 4 var cartographic = Cesium.Cartographic.fromCartesian(dayantaTileset.boundingSphere.center); 5 var surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height); 6 var offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height + height); 7 var translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3()); 8 palaceTileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); 9 })
或者通过指定经纬高调整模型位置:
1 var longitude = 116.3908443995411; 2 var latitude = 39.91600579431837; 3 height = 60.38590702090875; 4 var heading = 2; 5 palaceTileset.readyPromise.then(function(argument) { 6 //经纬度、高转笛卡尔坐标 7 var position = Cesium.Cartesian3.fromDegrees(longitude, latitude, height); 8 var mat = Cesium.Transforms.eastNorthUpToFixedFrame(position); 9 var rotationX = Cesium.Matrix4.fromRotationTranslation(Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(heading))); 10 Cesium.Matrix4.multiply(mat, rotationX, mat); 11 palaceTileset._root.transform = mat; 12 })
显示效果如下:
1、三维模型显示
由DAE格式模型转换而来,DAE文件与纹理图片在同一级文件夹下,可成功转换出待纹理的3dTiles,否则找不到纹理图片就只有白模;
2、倾斜摄影场景显示
由osgb数据转换而来,cesiumlab中转换时要选择data目录,如下图:
加载显示结果如下:
3、矢量建筑物显示
由shapefile格式的建筑物多边形数据转换而来,包含建筑物高度信息,矢量物批量显示,不用调整建筑物位置,显示效果如下:
建筑物按高度用颜色区分,设置了tileset的样式如下:
1 //注意这个颜色的设置 2 tileset.style = new Cesium.Cesium3DTileStyle({ 3 color: { 4 conditions: [ 5 ['${height} >= 200', 'color("red", 1)'], 6 ['${height} >= 100', 'rgba(150, 150, 150, 1)'], 7 ['true', 'color("blue")'] 8 ] 9 } 10 });
其中height为shapefile中存储建筑物高度的属性字段名称,建筑物选择显示属性信息通过侦听鼠标MOVE和LEFT_CLICK事件,查询要素获得,实现代码如下:
1 // HTML overlay for showing feature name on mouseover 2 var nameOverlay = document.createElement('div'); 3 viewer.container.appendChild(nameOverlay); 4 nameOverlay.className = 'backdrop'; 5 nameOverlay.style.display = 'none'; 6 nameOverlay.style.position = 'absolute'; 7 nameOverlay.style.bottom = '0'; 8 nameOverlay.style.left = '0'; 9 nameOverlay.style['pointer-events'] = 'none'; 10 nameOverlay.style.padding = '4px'; 11 nameOverlay.style.backgroundColor = 'yellowgreen'; 12 13 // Information about the currently selected feature 14 var selected = { 15 feature: undefined, 16 originalColor: new Cesium.Color() 17 }; 18 19 // An entity object which will hold info about the currently selected feature for infobox display 20 var selectedEntity = new Cesium.Entity(); 21 22 // Get default left click handler for when a feature is not picked on left click 23 var clickHandler = viewer.screenSpaceEventHandler.getInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); 24 25 // Change the feature color. 26 // Information about the currently highlighted feature 27 var highlighted = { 28 feature: undefined, 29 originalColor: new Cesium.Color() 30 }; 31 32 // Color a feature yellow on hover. 33 viewer.screenSpaceEventHandler.setInputAction(function onMouseMove(movement) { 34 // If a feature was previously highlighted, undo the highlight 35 if(Cesium.defined(highlighted.feature)) { 36 highlighted.feature.color = highlighted.originalColor; 37 highlighted.feature = undefined; 38 } 39 // Pick a new feature 40 var pickedFeature = viewer.scene.pick(movement.endPosition); 41 if(!Cesium.defined(pickedFeature) || !Cesium.defined(pickedFeature.getProperty)) { 42 nameOverlay.style.display = 'none'; 43 return; 44 } 45 // A feature was picked, so show it's overlay content 46 nameOverlay.style.display = 'block'; 47 nameOverlay.style.bottom = viewer.canvas.clientHeight - movement.endPosition.y + 'px'; 48 nameOverlay.style.left = movement.endPosition.x + 'px'; 49 var name = pickedFeature.getProperty('name'); 50 if(!Cesium.defined(name)) { 51 name = pickedFeature.getProperty('id'); 52 } 53 nameOverlay.textContent = name; 54 // Highlight the feature if it's not already selected. 55 if(pickedFeature !== selected.feature) { 56 highlighted.feature = pickedFeature; 57 Cesium.Color.clone(pickedFeature.color, highlighted.originalColor); 58 pickedFeature.color = Cesium.Color.YELLOW.withAlpha(0.5); 59 } 60 }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); 61 62 // Color a feature on selection and show metadata in the InfoBox. 63 viewer.screenSpaceEventHandler.setInputAction(function onLeftClick(movement) { 64 // If a feature was previously selected, undo the highlight 65 if(Cesium.defined(selected.feature)) { 66 selected.feature.color = selected.originalColor; 67 selected.feature = undefined; 68 } 69 // Pick a new feature 70 var pickedFeature = viewer.scene.pick(movement.position); 71 if(!Cesium.defined(pickedFeature) || !Cesium.defined(pickedFeature.getProperty)) { 72 clickHandler(movement); 73 return; 74 } 75 // Select the feature if it's not already selected 76 if(selected.feature === pickedFeature) { 77 return; 78 } 79 selected.feature = pickedFeature; 80 console.log(pickedFeature.content.tile.boundingSphere.center); 81 console.log(pickedFeature.tileset.boundingSphere.center); 82 // Save the selected feature's original color 83 if(pickedFeature === highlighted.feature) { 84 Cesium.Color.clone(highlighted.originalColor, selected.originalColor); 85 highlighted.feature = undefined; 86 } else { 87 Cesium.Color.clone(pickedFeature.color, selected.originalColor); 88 } 89 // Highlight newly selected feature 90 pickedFeature.color = Cesium.Color.LIME.withAlpha(0.5); 91 // Set feature infobox description 92 var featureName = pickedFeature.getProperty('name'); 93 selectedEntity.name = featureName; 94 selectedEntity.description = 'Loading <div class="cesium-infoBox-loading"></div>'; 95 96 selectedEntity.description = '<table class="cesium-infoBox-defaultTable"><tbody>'; 97 var propertyNames = pickedFeature.getPropertyNames(); 98 var length = propertyNames.length; 99 for(var i = 0; i < length; ++i) { 100 var propertyName = propertyNames[i]; 101 selectedEntity.description += '<tr><th>' + propertyName + '</th><td>' + pickedFeature.getProperty(propertyName) + '</td></tr>'; 102 } 103 selectedEntity.description += '</tbody></table>'; 104 viewer.selectedEntity = selectedEntity; 105 106 }, Cesium.ScreenSpaceEventType.LEFT_CLICK);