cesium# 系列文章目录
加载3D建筑
示例cesium版本为1.116.0
初始化
const viewer = new Cesium.Viewer("cesiumContainer", {
baseLayerPicker: false,
terrainProvider: await Cesium.CesiumTerrainProvider.fromIonAssetId(1, {
requestVertexNormals: true, //可以增加法线,用于提高光照效果
requestWaterMask: true, //可以增加水面特效
})
});
加载cesium
提供的通用3D建筑
首先要到cesium
的个人中心,资源仓库中添加Cesium OSM Buildings
到自己的资源中,这种资源的建筑没有高度
const tileset = viewer.scene.primitives.add(
await Cesium.Cesium3DTileset.fromIonAssetId(96188),
);
//移动视角到陆家嘴
viewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(121.49,31.23, 3000),
orientation: {
heading: 0,
pitch: -90,
roll: 0
}
})
未加载模型前:
加载模型后:
添加有高度的建筑
纽约3D建筑
到cesium
的个人中心,资源仓库中添加New York City 3D Buildings
到自己的资源中
const tileset = viewer.scene.primitives.add(
await Cesium.Cesium3DTileset.fromIonAssetId(75343),
);
//可以根据高度,修改模型颜色
//移动视角到纽约,像上方一样,设置视角,也可以直接这么做
viewer.zoomTo(tileset)
结果如下:
-
根据高度设置建筑颜色
ps:高度的顺序,因为我们用的是大于号一定要从大到小,反之则是从小到大
tileset.style = new Cesium.Cesium3DTileStyle({ color: { conditions: [ ['${Height} >= 300', 'rgba(45,0,75,0.6)'], ['${Height} >= 200', 'rgba(102,71,151, 1)'], ['${Height} >= 100', 'rgba(170,62,204, 1)'], ['${Height} >= 50', 'rgba(224,226,238, 1)'], ['${Height} >= 25', 'rgba(252,230,200, 1)'], ['${Height} >= 10', 'rgba(248,176,87, 1)'], ['${Height} >= 5', 'rgba(198,106,11, 1)'], ['true', 'rgba(127,59,8, 1)'], ] }, show: '${Height} >= 0', });
结果如下:
-
根据经纬度设置建筑颜色
tileset.style = new Cesium.Cesium3DTileStyle({ color: { conditions: [ ['${Latitude} >= 40.712945742423585', 'rgba(255, 0, 0, 1.0)'], //红色 ['${Latitude} >= 40.64859281217332', 'rgba(0, 0, 255, 0.5)'], // 蓝色 ['${Latitude} >= 40.607812909160636', 'rgba(255, 0, 0, 0.7)'], // 红色 ] }, show: '${Height} >= 0', });
结果如下:
-
以某一点为圆点,根据到原点的距离设置颜色
tileset.style = new Cesium.Cesium3DTileStyle({ defines: { distance: "distance(vec2(${Latitude},${Longitude}),vec2(40.712945742423585, -74.01312421751199))", }, color: { conditions: [ ["${distance} < 0.04", "color('red', 1.0)"], //红 ["${distance} < 0.05", "color('orange', 1.0)"], //橙 ["${distance} < 0.06", "color('yellow', 1.0)"], //黄 ["${distance} < 0.07", "color('green', 1.0)"], //绿 ["${distance} < 0.08", "color('cyan', 1.0)"], //青 ["${distance} < 0.09", "color('blue', 1.0)"], //蓝 ["${distance} < 0.10", "color('purple', 1.0)"], //紫 ["true", "color('#ADD8E6',0.8)"], ] }, show: '${Height} >= 0', });
结果如下:
-
添加鼠标经过建筑物的事件,这里做两个小功能
- 鼠标经过建筑物的时候高亮
- 鼠标经过建筑物的时候,悬浮显示一些关于建筑物的信息
const scene = viewer.scene const handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); //处理事件 const highlighted = { feature: undefined, originalColor: new Cesium.Color(), }; const selected = { feature: undefined, originalColor: new Cesium.Color(), }; const metadataOverlay = document.createElement("div"); viewer.container.appendChild(metadataOverlay); //弹窗tips的样式 metadataOverlay.className = "backdrop"; metadataOverlay.style.display = "none"; metadataOverlay.style.position = "absolute"; metadataOverlay.style.bottom = "0"; metadataOverlay.style.left = "0"; metadataOverlay.style["pointer-events"] = "none"; //设置元素是否对鼠标事件做出反应 metadataOverlay.style.padding = "4px"; metadataOverlay.style.backgroundColor = "#303030"; metadataOverlay.style.whiteSpace = "pre-line"; metadataOverlay.style.fontSize = "16px"; metadataOverlay.style.borderRadius = "4px"; //添加想要处理的回调函数 handler.setInputAction(function (movement) { //movement:startPosition开始位置,endPosition结束位置(代表当前模型位置) if (true) { if (Cesium.defined(highlighted.feature)) { highlighted.feature.color = highlighted.originalColor; highlighted.feature = undefined; } //返回一个带有“primitive”属性的对象,该属性包含场景中位于特定窗口坐标处的第一个图元(顶部),如果该位置没有任何内容,则返回undefined const feature = scene.pick(movement.endPosition); const featurePicked = feature instanceof Cesium.Cesium3DTileFeature; //是否包含此属性 const isBuildingFeature = featurePicked && feature.hasProperty("Majority_Ownership_Type"); if (isBuildingFeature) { if (feature !== selected.feature) { highlighted.feature = feature; Cesium.Color.clone(feature.color, highlighted.originalColor); feature.color = Cesium.Color.AQUA; } metadataOverlay.style.display = "block"; metadataOverlay.style.bottom = `${viewer.canvas.clientHeight - movement.endPosition.y}px`; metadataOverlay.style.left = `${movement.endPosition.x}px`; var tableHtmlScratch = `<div style="color: #fff">${feature.getProperty( "Majority_Ownership_Type")}</div>` metadataOverlay.innerHTML = tableHtmlScratch; } else { metadataOverlay.style.display = "none"; } } }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
自定义模型
上面的模型都是cesium
自带的,如果是自己的模型,怎么加载呢?有两种方式:
-
通过
Cesium3DTileset.fromUrl
方式[官网地址](Cesium3DTileset - Cesium Documentation)const tileset = viewer.scene.primitives.add( await Cesium.Cesium3DTileset.fromUrl("/tileset/Photogrammetry/tileset.json") );
-
上传到cesiumion自己的资源中,会生成一个
id
,然后用前面的方法