• 在maptalks中加载三维模型obj,fbx,glb


    • maptalks 是一个基于WebGL的三维地图js库,基于maptalks可以快速建立web三维地图,加载各种地图数据,生成对应的图层,加载三维模型等。

    •  地图加载。maptalks支持标准的地图数据类型,如GeoJson,TileServer等。

        GeoJson格式是一种地理信息对象描述文件,可以是本地的,也可以存储在远程服务器上,其基本格式如下:

        

    {
    "type": "FeatureCollection",
    "name": "line0706",
    "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
    "features": [
    { "type": "Feature", "properties": { "id": 26, "OID": 26, "PID": "1JS2036-1JS2037", "Shape_Length": 215.78135367381537, "linegj": 400.0, "linecz": "球墨铸铁" }, "geometry": { "type": "LineString", "coordinates": [ [ 117.139587450494673, 31.980963606892612 ], [ 117.141572764515146, 31.980002698897021 ] ] } },
    { "type": "Feature", "properties": { "id": 27, "OID": 27, "PID": "1JS2037-1JS2038", "Shape_Length": 174.33523286131555, "linegj": 400.0, "linecz": "球墨铸铁" }, "geometry": { "type": "LineString", "coordinates": [ [ 117.141572764515146, 31.980002698897021 ], [ 117.143128167657636, 31.979157606398935 ] ] } },
    { "type": "Feature", "properties": { "id": 28, "OID": 28, "PID": "1JS2038-AJS2720", "Shape_Length": 74.157593232456321, "linegj": 400.0, "linecz": "球墨铸铁" }, "geometry": { "type": "LineString", "coordinates": [ [ 117.143128167657636, 31.979157606398935 ], [ 117.143830270406454, 31.978859076104776 ] ] } },
    { "type": "Feature", "properties": { "id": 29, "OID": 29, "PID": "1JS2039-DJS504", "Shape_Length": 116.76683212772929, "linegj": 400.0, "linecz": "球墨铸铁" }, "geometry": { "type": "LineString", "coordinates": [ [ 117.146490176708213, 31.977233403153686 ], [ 117.147518501281553, 31.9766498062083 ] ] } },
    { "type": "Feature", "properties": { "id": 30, "OID": 30, "PID": "1JS2040-1JS2041", "Shape_Length": 346.5596390599348, "linegj": 400.0, "linecz": "球墨铸铁" }, "geometry": { "type": "LineString", "coordinates": [ [ 117.148207019802612, 31.976299944711535 ], [ 117.151189187226777, 31.974481644858205 ] ] } }
    ]
    }

      

        可以看出,geoJson格式是在Json数据格式的基础上增加了关于GIS的一些属性描述信息,

        如type:Feature表示是一个地理对象,properties表示对象的属性值,geometry表示要描述的地理对象,

        里面type:LineString表示类型是一个线段, coordinates 表示坐标,后面接着的数组表示一组坐标值,来表示起始点坐标位置。

      

      ArcGISTileLayer

         let ArcGIS_Layer = new maptalks.ArcGISTileLayer('line', {
    
              visible: true,
    
              urlTemplate: 'http://127.0.0.1:6080/server/rest/services/line/MapServer',
    
         });

        urlTemplate对应的值就是已经部署在ArcGIS服务器上的地图服务地址。

    • 三维模型。基于maptalks 有一个使用threejs开发 maptalks.threeLayer 库,可以在maptalks中直接引用,在maptalks中加载三维模型,其实就是使用threejs加载三维模型。

       常用的三维模型有以下几种,obj,fbx,glb。使用同一个模型导出的三种文件格式大小如下图:

      

      从文件大小看,fbx和glb更有优势。

      使用Windows自带的3D模型打开Wie

       obj模型一般情况下包含2-3个文件,obj,mtl,jpg(png), obj 为模型文件,mtl 和 jpg文件为材质文件,obj文件可以通过文本编辑器打开,可以看到里面指定了该obj文件对应的材质文件的名称。其余的是在三维空间中绘制的点位置。

        

       需要使用材质的位置则指定使用mtl文件中的材质名称。

         

       在mtl文件中,则可以看到该材质的名称对应的参数

        

      fbx文件和glb为二进制编码后的文件,使用文本编辑器打开为乱码。

      从可读性看,obj文件更占优势。

    • 使用maptalks.threelayer 加载三维模型

        threejs针对obj、fbx、glb三种格式的三维模型有专门的示例,针对threejs加载,可以在其官网 https://threejs.org/examples 查看,这里专门讲解maptalks 地图中的加载。

        首先,threejs 提供了用于专门解析模型的 js 文件,  

        

        需要注意的是:在使用的过程中,需要确认 maptalks.js, maptalks.threelayer.js, 与 OBJLoader.js,MTLLoader.js,FBXLoader.js,GLTFLoader.js所引用three.js 版本一致,否则会出现函数不兼容的情况,无法调用成功。

        加载obj的方法为:     

     new THREE.MTLLoader(manager)
                    .setPath('/js/symap/lib/maptalks/models/obj/ws/')
                    .load('gs.mtl', function (materials) {
    
                        materials.preload();
    
                        new THREE.OBJLoader(manager)
                            .setMaterials(materials)
                            .setPath('/js/symap/lib/maptalks/models/obj/ws/')
                            .load('gs.obj', function (object) {
    
                                object.traverse(function (child) {
                                    if (child instanceof THREE.Mesh) {
                                        child.scale.set(0.01, 0.01, 0.01);
                                        child.rotation.set(Math.PI * 1 / 2, Math.PI * 1 / 8, 0);
                                    }
                                });
    
                                _this.getObject3d().add(object);
    
                                const z = layer.distanceToVector3(50, 50).x;
                                const position = layer.coordinateToVector3(
                                    coordinate,
                                    z
                                );
    
                                _this.getObject3d().position.copy(position);
    
                            });
                    });

        加载 fbx 的方法为:

    var loader = new THREE.FBXLoader();
                loader.load('/js/symap/lib/maptalks/models/fbx/beng.fbx', function (object) {
    
                    object.scale.set(0.002, 0.002, 0.002);
                    object.rotation.set(-Math.PI * 1 / 2, -Math.PI * 1 / 2, 0);
    
                    _this._mixer = new THREE.AnimationMixer(object);
    
                    const action = _this._mixer.clipAction(object.animations[0]);
    
                    if (title.indexOf("测试") > -1) { //速度不为0,显示运转
                        action.stop();
                    } else {
                        action.play();
                    }
    
                    object.traverse(function (child) {
    
                        if (child.isMesh) {
    
                            if (child.name == "bengke") {
    
                                child.material.visible = false;
    
                            }
    
                            child.castShadow = true;
                            child.receiveShadow = true;
    
                        }
    
                    });
    
                    _this.getObject3d().add(object);
    
                    const z = layer.distanceToVector3(150, 150).x;
                    const position = layer.coordinateToVector3(
                        coordinate,
                        z
                    );
                    _this.getObject3d().position.copy(position);
    
                });

        加载 glb 文件的方法为:

    var gltfLoader = new THREE.GLTFLoader(manager);
    
                const dracoLoader = new THREE.DRACOLoader(manager);
    
                gltfLoader.setDRACOLoader(dracoLoader);
    
                gltfLoader.setPath('/js/symap/lib/maptalks/models/gltf/');
                gltfLoader.load('gssb.glb', function (gltf) {
    
                    var object = gltf.scene;
                    object.scale.set(0.3, 0.3, 0.3);
                    _this.getObject3d().add(object);
    
                    object.traverse(function (child) {
                        if (child instanceof THREE.Mesh) {
                            //if (child.name == "bengke") {
                            //    child.material.visible = false;
                            //}
                            child.rotation.set(Math.PI * 1 / 2, 0, 0);
                            child.scale.set(0.1, 0.1, 0.1);
                        }
                    });
    
                    const z = layer.distanceToVector3(150, 150).x;
                    const position = layer.coordinateToVector3(
                        coordinate,
                        z
                    );
    
                    _this.getObject3d().position.copy(position);
    
                    _this._mixer = new THREE.AnimationMixer(object);
                    var clip = gltf.animations[0];
                    _this._mixer.clipAction(clip.optimize()).play();
    
                });

        在glb的加载中,另外引用了一个 DRACOLoader.js 这是一个js库可以在模型加载的过程中对模型进行压缩。

        踩坑记录:

        在3D软件设计模型时,将模型放在(0,0,0)的位置,否则模型加载后不能出现在Scene中,或者不在代码设定的位置上。

        另外对比同一开发环境下单个模型的加载方式对比: 支持   不支持  待测

    格式

    大小

    多文件

    可读性

    加载速度

    支持动画

    运行压缩

    预压缩

    备注

    Obj

    17.36M

         

    30ms

           

    fbx

    6.3M

         

    21ms

            

    glb

    8.3

         

    25ms

            

     

        在此次测试中,从加载时间来看,fbx>glb>obj ,综合网络搜索结果,glb模型对其它三维GIS软件(Cesium,CityEngine)的兼容性更好,所以在本项目中使用glb格式的三维模型文件。

        下图为在maptalks中加载的三维模型:

         

        针对模型较大的问题,网上还有其它解决方法,比如DRACOLoader将模型压缩为drc文件进行加载;大模型拆分小模型然后分别压缩drc文件加载;精细模型减少内部结构,保留表面减少模型实际大小等,在开发中再进行测试。

  • 相关阅读:
    jenkins+tomcat+python+pytest的web自动化化部署
    windows的jenkins+tomcat工作目录配置(这个要安装前就提前确定好,这种方法会导致整个jenkins重置)
    pytest xunit2 in pytest6.0
    Jenkins基本配置一
    React生命周期函数的使用场景
    React中的生命周期函数(老版本V16.0之前)
    React中ref的使用
    React中setState注意事项
    React之虚拟DOM中的Diff算法
    React之深入了解虚拟DOM
  • 原文地址:https://www.cnblogs.com/googlegis/p/13963519.html
Copyright © 2020-2023  润新知