Cesium显示倾斜摄影模型


化石原创文章,转载请注明来源并保留原文链接


拿到手的这个倾斜摄影数据是一个文件夹,里面放置osgb.s3c,metadata.xml,和一个Data目录。Data目录有一堆Tile文件夹,里面放置了很多的osgb后缀的文件-Smart3D处理过的Open Scene Graph Binary文件。

注:

metadata.xml中的信息有SRS和SRSOrigin,分别对应模型建立的坐标系,和原点位置。如下,SRSOrigin可以在epsg.io网站上查EPSG:4544下的地点,就是该模型的中心位置。

<SRS>EPSG:4544</SRS>
<!--Origin in Spatial Reference System-->
<SRSOrigin>701356,3307142,0</SRSOrigin>

查了一下网络,需要用一些工具转化该数据集才能在Cesium中显示,因为Cesium目前只支持3D tiles。

1、 https://github.com/fanvanzh/3dtiles 这里下载预编译好的一个工具

windows版预编译好的下载:

链接:https://pan.baidu.com/s/1jZcSVIUoYNtMQdxbo4xJCQ
提取码:qjsj

2、命令行打开,使用下面的命令把拿到手的文件夹里的数据转化成3d tiles,会生成在./output下

3dtile -f osgb -i ./ -o ./output

3、拷贝./output里的3d tiles文件到Cesium的工程目录,用下面的代码显示

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
    <meta name="description" content="Demo the minimum set of options needed to remove all external dependencies, for offline operation.">
    <meta name="cesium-sandcastle-labels" content="Beginner, Showcases">
    <title>Cesium Demo</title>
    <script type="text/javascript" src="../Sandcastle-header.js"></script>
    <script type="text/javascript" src="../../../ThirdParty/requirejs-2.1.20/require.js"></script>
    <script type="text/javascript">
    require.config({
        baseUrl : '../../../Source',
        waitSeconds : 60
    });
    </script>
</head>
<body class="sandcastle-loading" data-sandcastle-bucket="bucket-requirejs.html">
<style>
    @import url(../templates/bucket.css);
</style>
<div id="cesiumContainer" class="fullSize"></div>
<div id="loadingOverlay"><h1>Loading...</h1></div>
<div id="toolbar"></div>
<script id="cesium_sandcastle_script">
    function startup(Cesium) {
        'use strict';
  
        var fixGltf = function(gltf) {
            if (!gltf.extensionsUsed) {
                return;
            }

            var v = gltf.extensionsUsed.indexOf('KHR_technique_webgl');
            var t = gltf.extensionsRequired.indexOf('KHR_technique_webgl');
            // 中招了。。
            if (v !== -1) {
                gltf.extensionsRequired.splice(t, 1, 'KHR_techniques_webgl');
                gltf.extensionsUsed.splice(v, 1, 'KHR_techniques_webgl');
                gltf.extensions = gltf.extensions || {};
                gltf.extensions['KHR_techniques_webgl'] = {};
                gltf.extensions['KHR_techniques_webgl'].programs = gltf.programs;
                gltf.extensions['KHR_techniques_webgl'].shaders = gltf.shaders;
                gltf.extensions['KHR_techniques_webgl'].techniques = gltf.techniques;
                var techniques = gltf.extensions['KHR_techniques_webgl'].techniques;

                gltf.materials.forEach(function (mat, index) {
                    gltf.materials[index].extensions['KHR_technique_webgl'].values = gltf.materials[index].values;
                    gltf.materials[index].extensions['KHR_techniques_webgl'] = gltf.materials[index].extensions['KHR_technique_webgl'];

                    var vtxfMaterialExtension = gltf.materials[index].extensions['KHR_techniques_webgl'];

                    for (var value in vtxfMaterialExtension.values) {
                        var us = techniques[vtxfMaterialExtension.technique].uniforms;
                        for (var key in us) {
                            if (us[key] === value) {
                                vtxfMaterialExtension.values[key] = vtxfMaterialExtension.values[value];
                                delete vtxfMaterialExtension.values[value];
                                break;
                            }
                        }
                    };
                });

                techniques.forEach(function (t) {
                    for (var attribute in t.attributes) {
                        var name = t.attributes[attribute];
                        t.attributes[attribute] = t.parameters[name];
                    };

                    for (var uniform in t.uniforms) {
                        var name = t.uniforms[uniform];
                        t.uniforms[uniform] = t.parameters[name];
                    };
                });
            }
        }

        Object.defineProperties(Cesium.Model.prototype, {
            _cachedGltf: {
                set: function (value) {
                    this._vtxf_cachedGltf = value;
                    if (this._vtxf_cachedGltf &amp;&amp; this._vtxf_cachedGltf._gltf) {
                        fixGltf(this._vtxf_cachedGltf._gltf);
                    }
                },
                get: function () {
                    return this._vtxf_cachedGltf;
                }
            }
        });



        //Sandcastle_Begin
        // This is an example of using Cesium "Offline", meaning disconnected from the
        // external Internet.  It must still be served from a local web server, but
        // does not rely on any outside resources or services.  For more info, see:
        // https://github.com/AnalyticalGraphicsInc/cesium/wiki/Offline-Guide
        var viewer = new Cesium.Viewer('cesiumContainer', {
            imageryProvider : Cesium.createTileMapServiceImageryProvider({
                url : Cesium.buildModuleUrl('Assets/Textures/NaturalEarthII')
            }),
            baseLayerPicker : false,
            geocoder : false
        });

        var tileset = new Cesium.Cesium3DTileset({
            url: '../../SampleData/Cesium3DTiles/fromyuzs/tileset.json'
        });

        viewer.scene.primitives.add(tileset);
        viewer.zoomTo(tileset);

        //viewer.scene.debugShowGlobeDepth = true;
        //Sandcastle_End
        Sandcastle.finishedLoading();
    }
    if (typeof Cesium !== 'undefined') {
        startup(Cesium);
    } else if (typeof require === 'function') {
        require(['Cesium'], startup);
    }
</script>
</body>
</html>

注意:代码使用了网络上找到的fixGltf方式,否则Cesium显示这个3d tiles的时候会出错。


化石原创文章,转载请注明来源并保留原文链接


发表评论

电子邮件地址不会被公开。 必填项已用*标注