Cesium实现三维可视化一般步骤

在项目的开发过程中用到在底图显示三维可视化图形,涉及到加载大批量的数据,经过查阅资料,决定采用Cesium设计一个实现方案,在底图显示3d模型以及与3d模型之间的一系列交互行为,下面分步骤详细进行介绍:

  1. 创建查看器—将查看器添加到指定的铯容器cesiumContainer,可以实现底图的切换,加载天地图。代码如下所示:
var viewer = new Cesium.Viewer('cesiumContainer', {
        imageryProvider : new Cesium.createOpenStreetMapImageryProvider({
            url : 'https://a.tile.openstreetmap.org/'
        }),
        baseLayerPicker : false,
        animation : false,
        timeline : false,
        fullscreenButton : false,
        infoBox : false,
        homeButton : false
    });

2.相机控制—由属性viewer.scene控制当前可见的内容,可以通过设置相机的位置和方向来控制相机切换视角,也可以使用cesium相机API来设置相机的位置和方向。

//Create an initial camera view
    var initialPosition = new Cesium.Cartesian3.fromDegrees(-73.848114468289017509, 40.824512895646692812, 2631.082799425431);
    var initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees(7.1077496389876024807, -31.987223091598949054, 0.025883251314954971306);
    var homeCameraView = {
        destination : initialPosition,
        orientation : {
            heading : initialOrientation.heading,//围绕负z轴的旋转
            pitch : initialOrientation.pitch,//围绕负y轴的旋转
            roll : initialOrientation.roll//围绕正x轴的旋转
        }
    };
    viewer.scene.camera.setView(homeCameraView);  //将相机设定在特定的位置和方向

3.加载样式实体—为了便于观看,cesium支持流行的矢量格式GeoJson和KML,以及我们专门为描述cesium中称为CZML的场景而开发的开放格式。其中DataSource只是定义了一个接口,需要的确切类型的数据源将取决于数据格式。

(1) KML使用KmlDataSource,通过调用KmlDataSource.load(optinos)几个选项从KML文件中读取我们的示例geocache点。对于KmlDataSource,需要相机和画布选项。该clampToGround选项支持地面夹紧,这是一种流行的显示选项,可使地形几何实体(如多边形和椭圆)符合地形而不是曲线到WGS84椭球表面。

var kmlOptions = {
        camera : viewer.scene.camera,//相机选项
        canvas : viewer.scene.canvas,//画布选项
        clampToGround : true
    };
    // Load geocache points of interest from a KML file
    var geocachePromise = Cesium.KmlDataSource.load('./SampleData/kml/bikeRide.kml', kmlOptions);
    // Add geocache billboard entities to scene and style them
    geocachePromise.then(function(dataSource) {
        // Add the new data as entities to the viewer
        viewer.dataSources.add(dataSource);
        // Get the array of entities
        var geocacheEntities = dataSource.entities.values;
        for (var i = 0; i < geocacheEntities.length; i++) {
            var entity = geocacheEntities[i];
            if (Cesium.defined(entity.billboard)) {
                // Adjust the vertical origin so pins sit on terrain
                entity.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOM;
                // Disable the labels to reduce clutter
                entity.label = undefined;
                // Add distance display condition
                entity.billboard.distanceDisplayCondition = new Cesium.DistanceDisplayCondition(10.0, 20000.0);
                // Compute latitude and longitude in degrees
                var cartographicPosition = Cesium.Cartographic.fromCartesian(entity.position.getValue(Cesium.JulianDate.now()));
                var latitude = Cesium.Math.toDegrees(cartographicPosition.latitude);
                var longitude = Cesium.Math.toDegrees(cartographicPosition.longitude);
                // Modify description
                var description = '<table class="cesium-infoBox-defaultTable cesium-infoBox-defaultTable-lighter"><tbody>';
                description += '<tr><th>' + "Latitude" + '</th><td>' + latitude + '</td></tr>';
                description += '<tr><th>' + "Longitude" + '</th><td>' + longitude + '</td></tr>';
                description += '</tbody></table>';
                entity.description = description;
            }
        }
    });
(2) GeoJson与加载KML的过程非常相似,在这种情况下,可以使用GeoJsonDataSource代替,和前面的数据源一样,需要将viewer.dataSources添加数据到场景中。这种加载方式只是实现的平面的,可以通过自行设置高度entity.polygon.extrudedHeight读取每个实体属性中的高度
使建筑物看起来有一定的高度,切换视角,达到三维效果;加载geojson文件添加鼠标交互行为不生效;使用这种方式加载大批量的建筑物会造成浏览器卡顿甚至崩溃。
var geojsonOptions = {
        clampToGround : true
    };
    // Load neighborhood boundaries from KML file
    var neighborhoodsPromise = Cesium.GeoJsonDataSource.load('./SampleData/test.geojson', geojsonOptions);

    // Save an new entity collection of neighborhood data
    var neighborhoods;
    neighborhoodsPromise.then(function(dataSource) {
        // Add the new data as entities to the viewer
        var city = viewer.dataSources.add(dataSource);
        neighborhoods = dataSource.entities;
        // Get the array of entities
        var neighborhoodEntities = dataSource.entities.values;
        for (var i = 0; i < neighborhoodEntities.length; i++) {
            var entity = neighborhoodEntities[i];
            if (Cesium.defined(entity.polygon)) {
                // entity styling code here
                entity.name = entity.properties.neighborhood;
       //          entity.polygon.material = Cesium.Color.fromRandom({
                //     red : 0.4,
                //     maximumGreen :0.8,
                //     minimumBlue : 0.6,
                //     alpha :1
                // });
                entity.polygon.material = Cesium.Color.YELLOW;
                entity.polygon.outline = false;
                // Tells the polygon to color the terrain. ClassificationType.CESIUM_3D_TILE will color the 3D tileset, and ClassificationType.BOTH will color both the 3d tiles and terrain (BOTH is the default)
                entity.polygon.classificationType = Cesium.ClassificationType.TERRAIN;
                // Generate Polygon position
                var polyPositions = entity.polygon.hierarchy.getValue(Cesium.JulianDate.now()).positions;
                var polyCenter = Cesium.BoundingSphere.fromPoints(polyPositions).center;
                polyCenter = Cesium.Ellipsoid.WGS84.scaleToGeodeticSurface(polyCenter);
                entity.position = polyCenter;
                entity.polygon.extrudedHeight = entity.properties.height;
                // entity.polygon.height = entity.properties.height;
                // Generate labels
                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
                };
            }
        }
        //加载的建筑物的总数
        console.log(neighborhoodEntities.length);
    });
(3) Cesium支持基于glTF(GL传输格式)加载3D模型,加载模型与迄今为止我们使用过的任何其他类型的可视化没有什么不同,所需要的只是实体的位置和glTF模型的一个URL;每个模型都有自己的原始COLLADA文件(.dae)和glTF文件(.gltf),在Cesium中我们不需要原始的COLLADA文件,需要的只是经过3d
max转化后的gltf文件以及相应的贴图文件。(例子中定位到宾夕法尼亚州埃克斯顿就是通过加载.gltf格式的数据渲染到地图上)。
var scene = viewer.scene;
    var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(
    Cesium.Cartesian3.fromDegrees(-75.62898254394531, 40.02804946899414, 0.0));
    var model = scene.primitives.add(Cesium.Model.fromGltf({
        url : './SampleData/models/CesiumGround/Cesium_Ground.gltf',
        modelMatrix : modelMatrix,
        scale : 200.0
    }));

4、 鼠标交互—只有在加载3d Tiles的时候,才可以用鼠标实现交互选择和样式改变,否则这些模型将无法以交互方式查看。在这种情况下可以加载大批量的模型建筑物信息。例如viewer.scene.primitives.add(new Cesium.Cesium3DTileset({ url: Cesium.IonResource.fromAssetId(3839) }));显示纽约所有的建筑物完整的3d模型,从而为三维可视化添加真实感。

说明:如果要加载大批量的模型,以dataSource加载geojson文件的方法可能会造成浏览器卡顿甚至崩溃的现象;3d Tiles才是实现加载大规模场景应用的最佳选择,而且依赖于3d Tiles还可以实现鼠标交互改变样式等。

  • 6
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Cesium是一款三维地球可视化引擎,可以用来实现轨迹的可视化。下面,我将为您介绍使用Cesium实现轨迹可视化步骤。 1. 引入Cesium库文件 在HTML页面中引入Cesium库文件,可以从Cesium官网下载或使用CDN引入。 ```html <script src="https://cesium.com/downloads/cesiumjs/releases/1.83/Build/Cesium/Cesium.js"></script> <link href="https://cesium.com/downloads/cesiumjs/releases/1.83/Build/Cesium/Widgets/widgets.css" rel="stylesheet"> ``` 2. 创建Cesium Viewer对象 在JavaScript代码中创建Cesium Viewer对象,指定渲染区域和相机位置等参数。 ```javascript var viewer = new Cesium.Viewer("cesiumContainer", { terrainProvider: Cesium.createWorldTerrain(), imageryProvider: Cesium.createWorldImagery(), shouldAnimate: true, animation: false, timeline: false, }); viewer.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(-75.62898254394531, 40.02804946899414, 1500000), duration: 0, }); ``` 3. 加载轨迹数据 使用Cesium提供的`Entity`对象来加载轨迹数据,可以通过`position`属性设置轨迹的位置,通过`orientation`属性设置轨迹的方向。 ```javascript var positionProperty = new Cesium.SampledPositionProperty(); var orientationProperty = new Cesium.VelocityOrientationProperty(positionProperty); // 添加轨迹点 for (var i = 0; i < data.length; i++) { var time = Cesium.JulianDate.fromDate(new Date(data[i].time)); var position = Cesium.Cartesian3.fromDegrees(data[i].lon, data[i].lat, data[i].alt); positionProperty.addSample(time, position); } // 创建轨迹实体 var entity = viewer.entities.add({ name: 'Satellite', position: positionProperty, orientation: orientationProperty, point: { pixelSize: 5, color: Cesium.Color.RED, }, path: { show: true, leadTime: 0, trailTime: 60 * 60 * 24 * 30, resolution: 120, material: new Cesium.PolylineGlowMaterialProperty({ glowPower: 0.1, color: Cesium.Color.RED, }), width: 5, }, }); ``` 4. 设置动画效果 使用Cesium提供的`Clock`对象和`ClockViewModel`对象来设置动画效果,可以通过`startTime`和`stopTime`属性设置动画的起始时间和结束时间。 ```javascript var clock = new Cesium.Clock({ startTime: Cesium.JulianDate.fromDate(new Date(data[0].time)), stopTime: Cesium.JulianDate.fromDate(new Date(data[data.length - 1].time)), currentTime: Cesium.JulianDate.fromDate(new Date(data[0].time)), clockRange: Cesium.ClockRange.LOOP_STOP, clockStep: Cesium.ClockStep.SYSTEM_CLOCK_MULTIPLIER, }); var clockViewModel = new Cesium.ClockViewModel(clock); clockViewModel.shouldAnimate = true; viewer.timeline.zoomTo(clock.startTime, clock.stopTime); ``` 5. 运行代码 将上述代码复制到HTML文件中,并替换轨迹数据的具体数值,即可在浏览器中运行并查看轨迹可视化效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值