cesium加载b3dm格式的文件来实现分片式加载三维建筑物

刚开始用的是cesium加载geojson来达到加载三维建筑的目的,加载建筑物倒是没什么太大问题,只是建筑物还要进行贴图,如果再用geojson来加载贴图会特别卡,浏览器会崩溃,电脑会死机,于是发现官网有这种方法,加载完成之后速度特别快。而且是分片加载的,只加载视野区域内的建筑物,并且用这种方法来加载贴图也很快。但是加载之前本地必须引入xx.b3dm一个文件。否则加载不成功。

文档架构如下

cesium加载b3dm格式的文件来实现分片式加载三维建筑物_第1张图片

代码如下

Cesium.Ion.defaultAccessToken = "官网申请的token"

var viewer = new Cesium.Viewer('cesiumContainer', {
    imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
        url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
    }),
    animation: false,
    timeline: false,  //时间线
    fullscreenButton: true,  //全屏模式
    infoBox: false,  //要素信息框
    homeButton: false, //显示主页
    geocoder: false, //搜索位置
    sceneModePicker: true,//模式切换
    selectionIndicator: true, //展示三维的指示器
    navigationHelpButton: false, //帮助按钮
    navigationInstructionsInitiallyVisible: false
});
viewer.extend(Cesium.viewerCesiumNavigationMixin, {});  //添加指南针控件
//经度、纬度、建筑物视角高度
var initialPosition = new Cesium.Cartesian3.fromDegrees(117.11744684384189,39.128615983991416,500);
// var initialPosition = new Cesium.Cartesian3.fromDegrees(117.148,39.08135,500);

var initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees(7.1077496389876024807, -31.987223091598949050, 0.025883251314950971306);
var homeCameraView = {
    destination: initialPosition,
    orientation: {
        heading: initialOrientation.heading,//围绕负z轴的旋转
        pitch: initialOrientation.pitch,//围绕负y轴的旋转
        roll: initialOrientation.roll//围绕正x轴的旋转
    }
};
viewer.scene.camera.setView(homeCameraView);  //将相机设定在特定的位置和方向
//防止地面穿透
viewer.clock.onTick.addEventListener(function () {
    if (viewer.camera.pitch > -0.5) {
        viewer.scene.screenSpaceCameraController.enableTilt = false;
    }
});

var mousePosition, startMousePosition;
var handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
handler.setInputAction(function (movement) {
    mousePosition = startMousePosition = Cesium.Cartesian3.clone(movement.position);
    handler.setInputAction(function (movement) {
        mousePosition = movement.endPosition;
        var y = mousePosition.y - startMousePosition.y;
        // console.log(y)
        if (y > 0) {
            viewer.scene.screenSpaceCameraController.enableTilt = true;
        }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}, Cesium.ScreenSpaceEventType.MIDDLE_DOWN);


var layer = new Cesium.WebMapTileServiceImageryProvider({
    url: 'http://t0.tianditu.gov.cn/img_w/wmts?tk=42dca576db031641be0524ee977ddd04',
    layer: 'img',
    style: 'default',
    tileMatrixSetID: 'w',
    format: 'tiles',
    maximumLevel: 18

});

viewer.imageryLayers.addImageryProvider(layer);

var layer1 = new Cesium.WebMapTileServiceImageryProvider({
    url: 'http://t0.tianditu.gov.cn/cia_w/wmts?tk=42dca576db031641be0524ee977ddd04',
    layer: 'cia',
    style: 'default',
    tileMatrixSetID: 'w',
    format: 'tiles',
    maximumLevel: 18
});
viewer.imageryLayers.addImageryProvider(layer1);

以上是加载cesium默认一些鼠标事件,以及地图用的是天地图遥感影像图层。下面是加载建筑物的方法:

var tileset = new Cesium.Cesium3DTileset({
    url:"http://192.168.9.123:9002/api/folder/c942a82fcb8647d7b47c607e24ee36b4/tileset.json"
});
viewer.scene.primitives.add(tileset);

tileset.readyPromise.then(function(tileset) {
    viewer.scene.primitives.add(tileset);
    var heightOffset = 0;  //设置建筑物与地面的高度
    var boundingSphere = tileset.boundingSphere;
    var cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center);
    var surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0);
    var offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, heightOffset);
    var translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3());
    tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation);
    viewer.zoomTo(tileset, new Cesium.HeadingPitchRange(0.5, -0.2, tileset.boundingSphere.radius * 1.0));
});

tileset.readyPromise.then(function(argument) {
    var position = Cesium.Cartesian3.fromDegrees(longitude, latitude, height);
    var mat = Cesium.Transforms.eastNorthUpToFixedFrame(position);
    var rotationX = Cesium.Matrix4.fromRotationTranslation(Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(heading)));
    Cesium.Matrix4.multiply(mat, rotationX, mat);
    tileset._root.transform = mat;
    viewer.camera.flyTo({destination: Cesium.Cartesian3.fromDegrees(longitude, latitude, height + 1000)});
});


tileset.style = new Cesium.Cesium3DTileStyle({
    defines: {
        latitudeRadians: 'radians(${day})'
    },
    color: {
        conditions: [
            ['${day} < 200', "color('#C6C4C4')"]
        ]
    }
});

好了,这主要就是加载三维建筑物的代码,建筑物的配色是根据生成建筑物的文件里面的建筑物属性来配色的。那个tileset.json就是建筑物的数据接口。

加载贴图跟加载三维建筑物一样,这里是把贴图接口放入一个接口里了

$.ajax({
    url: "http://192.168.9.123:8090/SelectUrl",
    type: "post",
    async: true,
    dataType: "json",
    contentType: "application/x-www-form-urlencoded; charset=utf-8",
    success: function (data) {
        console.log(data)
        console.log(typeof data)
        for (var i = 0; i < data.length; i++) {
            var url = "http://192.168.9.123:9002/api/folder/"+data[i]+"/tileset.json"
            console.log(url)
            var imagetile = new Cesium.Cesium3DTileset({
                url:url   //贴图
            });

            viewer.scene.primitives.add(imagetile);
            imagetile.style = new Cesium.Cesium3DTileStyle({
                defines: {
                    latitudeRadians: 'radians(${day})'
                },
                color: {
                    conditions: [
                        ['${day} < 30', "color('#267300')"],
                        ['${day} >= 30 && ${day} < 35', "color('#5E8C00')"],
                        ['${day} >= 35 && ${day} < 40', "color('#A8A800')"],
                        ['${day} >= 40 && ${day} < 45', "color('#C48300')"],
                        ['${day} >= 45 && ${day} < 50', "color('#E04B00')"],
                        ['${day} >= 50 && ${day} < 55', "color('#FF0000')"],
                        ['${day} >= 55 && ${day} < 60', "color('#D41923')"],
                        ['${day} >= 60 && ${day} < 65', "color('#A82236')"],
                        ['${day} >= 65 && ${day} < 70', "color('#7D250A')"],
                        ['${day} >= 70 && ${day} < 75', "color('#4F275E')"],
                        ['${day} >=  75', "color('#002673')"]

                    ]
                }
            });
        }
    },
    error: function (data) {
        console.log(data)
    }
})

最后上效果图

建筑物效果:

cesium加载b3dm格式的文件来实现分片式加载三维建筑物_第2张图片

贴图效果:

cesium加载b3dm格式的文件来实现分片式加载三维建筑物_第3张图片

总之用这种方式加载比加载geojson快的不是一点。

你可能感兴趣的:(cesium)