此代码是我自己阅读cesium workshop 1.51时学习用的,经测试可用,直接上代码:
<!DOCTYPE html> <html lang="en"> <head> <!-- Use correct character set. --> <meta charset="utf-8"> <!-- Tell IE to use the latest, best version. --> <meta http-equiv="X-UA-Compatible" content="IE=Edge"> <!-- Make the app on mobile take up the full browser screen and disable user scaling. --> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"> <title>workshop2</title> <!-- The Cesium library. --> <script src="../ThirdParty/Cesium/Cesium.js"></script> <!-- Style our app. --> <link rel="stylesheet" href="../index.css" media="screen"> </head> <body> <div id="cesiumContainer"></div> <!-- Some input elements for our app. --> <div class="backdrop" id="menu"> <h2>Sample NYC Geocaches</h2> <span><strong>Camera Mode</strong></span> <div class="nowrap"> <input id="freeMode" name="source" type="radio" checked/> <label for="freeMode">Free</label> </div> <div class="nowrap"> <input id="droneMode" name="source" type="radio"/> <label for="droneMode">Drone View</label> </div> <br> <span><strong>3d Tile Styling</strong></span> <div class="nowrap"> <select id="tileStyle"> <option value="none">None</option> <option value="height">Height</option> <option value="transparent">Transparent</option> </select> </div> <br> <span><strong>Display Options</strong></span> <div class="nowrap"> <input id="shadows" type="checkbox"/> <label for="shadows">Shadows</label> </div> <div class="nowrap"> <input id="neighborhoods" type="checkbox" checked/> <label for="neighborhoods">Neighborhoods</label> </div> <br> </div> <div id="loadingIndicator" class="cover"> <div id="loadingIcon" class="loadingIndicator"></div> </div> <!--业务代码。--> <script> // Cesium 离子 默认密钥。 Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJiMGRjM2QxYi04ODM2LTQzMDEtOGJmOS1mNDlkY2Q2NjE4MjciLCJpZCI6MjU5LCJpYXQiOjE1MjU5NjYyMDd9.xW9loNLo68KE3ReAHd-Lp73M8qJKhI9vA0wYL-qJX_I'; // var viewer = new Cesium.Viewer('cesiumContainer'); // 创建带参数视图。 let viewer = new Cesium.Viewer('cesiumContainer', { scene3DOnly: true, // 只看3D场景。(场景模式选择器3D, 2D and Columbus View (CV)) selectionIndicator: false, // 作用未知。 baseLayerPicker: false // 基层拾取器。 }); // 设置时钟和时间线。 viewer.clock.shouldAnimate = true; // 在视图开始时,播放动画。 // 时间线开始时间(UTC). 2017-07-11 16:00:00 UTC. viewer.clock.startTime = Cesium.JulianDate.fromIso8601("2017-07-11T16:00:00Z"); // 时间线终止时间(UTC)。 viewer.clock.stopTime = Cesium.JulianDate.fromIso8601("2017-07-11T16:20:00Z"); // 时钟当前时间。 viewer.clock.currentTime = Cesium.JulianDate.fromIso8601("2017-07-11T16:00:00Z"); // 2倍速播放动画。 viewer.clock.multiplier = 2; // 滴答计算模式(感觉要和上一个参数联合使用) viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK_MULTIPLIER; // 末端循环,就是时间走到最后,从头再来,循环往复。 viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; // 设置时间线的可见范围。 viewer.timeline.zoomTo(viewer.clock.startTime, viewer.clock.stopTime); // 移除默认基层。 viewer.imageryLayers.remove(viewer.imageryLayers.get(0)); // 添加Sentinel-2 影像。 viewer.imageryLayers.addImageryProvider(new Cesium.IonImageryProvider({ assetId : 3954 })); // 加载 Cesium 世界地形。 viewer.terrainProvider = Cesium.createWorldTerrain({ requestWaterMask : true, // 水效应所需 requestVertexNormals : true // 地形照明所需。 }); // 启用深度测试,使地形后面的东西消失。 viewer.scene.globe.depthTestAgainstTerrain = true; // 启用 基于日月位置的 照明。(可以知道当前哪是白天,哪是黑夜。) // viewer.scene.globe.enableLighting = true; // 以下要创建初始视图 // 初始化位置。 let initialPosition = new Cesium.Cartesian3.fromDegrees(-73.998114468289017509, 40.674512895646692812, 2631.082799425431); // 初始化朝向。 let initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees(7.1077496389876024807, -31.987223091598949054, 0.025883251314954971306); let homeCameraView = { destination : initialPosition, // 目的地。 orientation : { heading : initialOrientation.heading, // 水平朝向 pitch : initialOrientation.pitch, // 俯仰角。 roll : initialOrientation.roll // 左右旋转。 } // 朝向定位。 }; // 设置初始视图 viewer.scene.camera.setView(homeCameraView); // 以下要重写默认的主视图,及飞到主视图之前的过渡效果。 // 添加一些相机飞行动画选项,主要用于flyTo函数的飞行效果。 homeCameraView.duration = 2.0; // 飞行时间2秒。 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); }); // 以下要从kml文件加载geocache兴趣点到视图。 // 文件加载选项。 let kmlOptions = { camera : viewer.scene.camera, canvas : viewer.scene.canvas, clampToGround : true }; // 加载。 // Data from : http://catalog.opendata.city/dataset/pediacities-nyc-neighborhoods/resource/91778048-3c58-449c-a3f9-365ed203e914 let geocachePromise = Cesium.KmlDataSource.load('../Source/SampleData/sampleGeocacheLocations.kml', kmlOptions); // 解析。 geocachePromise.then(function(dataSource){ // 将新数据作为实体添加到视图中。 viewer.dataSources.add(dataSource); // 获取实体数组,遍历每个实体,设置其样式。 let geocacheEntities = dataSource.entities.values; for (let i=0; i<geocacheEntities.length;i++){ let entity = geocacheEntities[i]; if (Cesium.defined(entity.billboard)){ // 调整垂直原点,使引脚固定在地形上。 entity.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOM; // 禁用标签以减少杂乱 entity.label = undefined; // 生成标签 // entity.label = { // text : entity.name, // showBackground : true, // scale : 0.6, // horizontalOrigin : Cesium.HorizontalOrigin.LEFT, // verticalOrigin : Cesium.VerticalOrigin.BOTTOM, // distanceDisplayCondition : new Cesium.DistanceDisplayCondition(10.0, 8000.0), // // disableDepthTestDistance : 100.0 // 可以是标签随时可见,不被实体遮挡。 // }; // 添加距离显示条件。(广告牌在10 - 2万米距离内显示。) entity.billboard.distanceDisplayCondition = new Cesium.DistanceDisplayCondition(10.0, 20000.0); // 以下要设置每个实体的 信息弹窗,弹窗标题是实体名称,内容只有经纬度。 // 获取此时此刻的实体位置。getValue(time, result),Cesium.JulianDate.now()创建表示当前系统时间的新实例。 let cartographicPosition = Cesium.Cartographic.fromCartesian(entity.position.getValue(Cesium.JulianDate.now())); // console.log("Cesium.JulianDate.now():", Cesium.JulianDate.now()); // JulianDate {dayNumber: 2458458, secondsOfDay: 69468.57} let longitude = Cesium.Math.toDegrees(cartographicPosition.longitude); let latitude = Cesium.Math.toDegrees(cartographicPosition.latitude); // 修改描述。 let description = '<table class="cesium-infoBox-defaultTable cesium-infoBox-defaultTable-lighter"><tbody>' + '<tr><th>' + "Longitude" + '</th><td>' + longitude.toFixed(5) + '</td></tr>' + '<tr><th>' + "Latitude" + '</th><td>' + latitude.toFixed(5) + '</td></tr>' + '</tbody></table>'; entity.description = description; } } }); // 以下要加载geojson类型的文件,用颜色分类不同的地块。 // 加载选项。 let geojsonOptions = { clampToGround : true // 紧贴地面。 }; // 从Geojson文件加载邻域边界 let neighborhoodsPromise = Cesium.GeoJsonDataSource.load('../Source/SampleData/sampleNeighborhoods.geojson', geojsonOptions); // 保存邻域数据的新实体集合。 let neighborhoods; neighborhoodsPromise.then(function(dataSource) { // 将新数据作为实体添加到查看器/视图中。 viewer.dataSources.add(dataSource); neighborhoods = dataSource.entities; // 获取实体数组。 let neighborhoodEntities = dataSource.entities.values; for (let i = 0; i < neighborhoodEntities.length; i++) { let entity = neighborhoodEntities[i]; if (Cesium.defined(entity.polygon)) { // 这里是实体样式代码: // 实体名称。 entity.name = entity.properties.neighborhood; // 将多边形材料设置为随机的半透明颜色。 entity.polygon.material = Cesium.Color.fromRandom({ red : 0.1, maximumGreen : 0.5, minimumBlue : 0.5, alpha : 0.6 }); // 告诉多边形给地形着色。 // 选项 ClassificationType.CESIUM_3D_TILE 将会为3D 区块集着色, // 选项 ClassificationType.BOTH 将同时为3d瓦片 和 地形着色。 (此选项是默认选项) entity.polygon.classificationType = Cesium.ClassificationType.TERRAIN; // 生成多边形位置 let polyPositions = entity.polygon.hierarchy.getValue(Cesium.JulianDate.now()).positions; // 获取多边形的平面中心。 let polyCenter = Cesium.BoundingSphere.fromPoints(polyPositions).center; // 把多边形的平面中心点,转换到WGS-84坐标系的椭球表面。 // WGS-84坐标系,一种国际上采用的地心坐标系,坐标原点为地球质心。 polyCenter = Cesium.Ellipsoid.WGS84.scaleToGeodeticSurface(polyCenter); entity.position = polyCenter; // 生成标签 entity.label = { text : entity.name, showBackground : true, scale : 0.6, horizontalOrigin : Cesium.HorizontalOrigin.CENTER, verticalOrigin : Cesium.VerticalOrigin.BOTTOM, distanceDisplayCondition : new Cesium.DistanceDisplayCondition(10.0, 8000.0), disableDepthTestDistance : 100.0 // 可以是标签随时可见,不被实体遮挡。 }; } } }); // 以下要从czml文件加载无人机飞行路径。 let dronePromise = Cesium.CzmlDataSource.load('../Source/SampleData/SampleFlight.czml'); let drone; // 无人机。 dronePromise.then(function(dataSource) { // 加载路径的动态效果。 viewer.dataSources.add(dataSource); // 使用czml数据中定义的id获取实体。 drone = dataSource.entities.getById('Aircraft/Aircraft1'); // 附加三维模型。 drone.model = { uri : '../Source/SampleData/Models/CesiumDrone.gltf', minimumPixelSize : 128, // 最小像素大小. maximumScale : 1000, // 最大标度. silhouetteColor : Cesium.Color.WHITE, // 轮廓颜色。 silhouetteSize : 2 // 轮廓尺寸。 }; // 根据抽样位置添加计算方向。 drone.orientation = new Cesium.VelocityOrientationProperty(drone.position); // 平滑路径插补。 drone.position.setInterpolationOptions({ interpolationDegree : 3, interpolationAlgorithm : Cesium.HermitePolynomialApproximation // 插补算法:Hermite多项式逼近 }); }); // 加载纽约的建筑物。 // city保存了整个建筑物实体模型。 let city = viewer.scene.primitives.add( new Cesium.Cesium3DTileset({ url: Cesium.IonResource.fromAssetId(3839) }) ); // 调整倾斜高度,使其不漂浮在地形之上。 let heightOffset = -32; // 向下偏移量。 city.readyPromise.then(function(tileset) { // 以下要重新定位倾斜模型。 // boundingSphere, 包容球。 let boundingSphere = tileset.boundingSphere; // 从笛卡尔位置创建一个新的制图实例。结果对象中的值将以弧度表示。 let cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center); // 从以弧度表示的经度和纬度值返回一个Cartesian 3位置。 let surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0); let offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, heightOffset); // 计算两个cartesian类型数据的差异。 let translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3()); tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); // console.log("tileset:", tileset); // console.log("tileset.boundingSphere:", tileset.boundingSphere); // console.log("boundingSphere.center:", boundingSphere.center); // console.log("cartographic:", cartographic); // console.log("surface:", surface); // console.log("offset:", offset); // console.log("translation:", translation); // console.log("tileset.modelMatrix:", tileset.modelMatrix); }); //以下要设置城市建筑的样式。 let defaultStyle = new Cesium.Cesium3DTileStyle({ color : "color('white')", show : true }); // city.style = defaultStyle; let transparentStyle = new Cesium.Cesium3DTileStyle({ color : "color('white', 0.3)", // 0,透明,1,不透明。 show : true }); // city.style = transparentStyle; let heightStyle = new Cesium.Cesium3DTileStyle({ color : { conditions : [ ["${height} >= 300", "rgba(45, 0, 75, 0.5)"], ["${height} >= 200", "rgb(102, 71, 151)"], ["${height} >= 100", "rgb(170, 162, 204)"], ["${height} >= 50", "rgb(224, 226, 238)"], ["${height} >= 25", "rgb(252, 230, 200)"], ["${height} >= 10", "rgb(248, 176, 87)"], ["${height} >= 5", "rgb(198, 106, 11)"], ["true", "rgb(127, 59, 8)"] ] } }); // city.style = heightStyle; // 以下要设置3d Tile Styling的下拉选项对应的样式。 let tileStyle = document.getElementById('tileStyle'); // 设置3D实体的样式。 function set3DTileStyle() { let selectedStyle = tileStyle.options[tileStyle.selectedIndex].value; if (selectedStyle === 'none') { city.style = defaultStyle; } else if (selectedStyle === 'height') { city.style = heightStyle; } else if (selectedStyle === 'transparent') { city.style = transparentStyle; } } // 给下拉列表添加“更改”事件,及其执行函数。 tileStyle.addEventListener('change', set3DTileStyle); let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); // 如果鼠标在兴趣点上,改变实体广告牌的比例和颜色。 let previousPickedEntity = undefined; handler.setInputAction(function(movement) { let pickedPrimitive = viewer.scene.pick(movement.endPosition); let pickedEntity = (Cesium.defined(pickedPrimitive)) ? pickedPrimitive.id : undefined; // 取消突出显示先前选定的实体。 if (Cesium.defined(previousPickedEntity)) { previousPickedEntity.billboard.scale = 1.0; previousPickedEntity.billboard.color = Cesium.Color.WHITE; } // 突出显示当前选定的实体。 if (Cesium.defined(pickedEntity) && Cesium.defined(pickedEntity.billboard)) { pickedEntity.billboard.scale = 2.0; pickedEntity.billboard.color = Cesium.Color.ORANGERED; previousPickedEntity = pickedEntity; } }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); // 以下要创建视图模式,(自由模式/家视图模式,无人机模式), // 通过camera mode下的单选按钮来选择即可。 // 获取两个模式的单选按钮元素。 let freeModeElement = document.getElementById('freeMode'); let droneModeElement = document.getElementById('droneMode'); // 通过跟踪无人机实体,创建跟踪摄像机 function setViewMode() { if (droneModeElement.checked) { viewer.trackedEntity = drone; } else { viewer.trackedEntity = undefined; viewer.scene.camera.flyTo(homeCameraView); } } // 为两个元素添加“change”事件及其处理函数。 freeModeElement.addEventListener('change', setViewMode); droneModeElement.addEventListener('change', setViewMode); // 双击无人机,转换到无人机模式时, 和 // 单击右上角的房子,转换到自由模式时, // 自动更新UI(Sample NYC Geocaches) viewer.trackedEntityChanged.addEventListener(function() { if (viewer.trackedEntity === drone) { freeModeElement.checked = false; droneModeElement.checked = true; } else { freeModeElement.checked = true; droneModeElement.checked = false; } }); // 以下要通过Display Options(显示选项)来操作,邻域边界的可见性。 // 选中Neighborhoods复选框,可见;否则,不可见。 // neighborhoodsElement,复选框元素。 let neighborhoodsElement = document.getElementById('neighborhoods'); // 给Neighborhoods复选框添加“change”事件,来控制邻域所有实体的可见性。 neighborhoodsElement.addEventListener('change', function (e) { // neighborhoods,所有邻域实体。 neighborhoods.show = e.target.checked; }); // 以下要通过shadows复选框,来操作/切换视图中的阴影效果。(主要体现在建筑物的阴面。) // 获取shadows复选框元素。 let shadowsElement = document.getElementById('shadows'); // 给该元素添加“change”事件。 shadowsElement.addEventListener('change', function (e) { // 根据shadows复选框的选中与否,决定视图的阴影有否。 viewer.shadows = e.target.checked; }); // 最后,等待城市完成初始化,再删除加载指示符。 // 加载指示符,其实是整个视图上层的一层黑幕布。网速好的情况下不会出现。 let loadingIndicator = document.getElementById('loadingIndicator'); loadingIndicator.style.display = 'block'; // city,整个建筑物实体模型,就绪/解析完成,隐藏加载指示符。 city.readyPromise.then(function () { loadingIndicator.style.display = 'none'; }); </script> </body> </html>