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

转:https://blog.csdn.net/du_5pet/article/details/95961311?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task


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

文档架构如下

代码如下

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)

    }

})

最后上效果图

建筑物效果:

贴图效果:

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

————————————————

版权声明:本文为CSDN博主「手机匿名用户」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/du_5pet/article/details/95961311

你可能感兴趣的:(cesium加载b3dm格式的文件来实现分片式加载三维建筑物)