获取某地模型并用Cesium加载(一)

 

2023-01-04

最近想用Cesium给学校做一个类似智慧校园的东西,要做的东西很多,首先是获取学校模型的问题,然后怎么用Cesium加载3Dtile

 

1.获取学校模型

想到之前被老师抓苦力去做春熙路的图,于是决定用比较熟悉的OSM数据集

https://www.openstreetmap.org/    需要梯子

进入后很容易就可以下载到所需区域的矢量数据

 

后续选择用ArcMap处理数据,但下载的OSM需要一个插件才能用ArcMap打开

https://github.com/Esri/arcgis-osm-editor

选择对应版本就可以了

在ArcMap里清洗并加上高度属性就可以了,大概是这个样子

 

 

 

如何变成3dtile格式呢,搜索了一下发现用CesiumLab最方便

 http://www.cesiumlab.com/

下载过后会在浏览器打开一个窗口

如果要将shp文件转换为3dtile,里面有文档跟着操作就可以了,上图那种数据量一秒就转换好了

 

2.Cesium加载3dtile

我是在vue里用的cesium,直接将刚才生成的3dtile放在static下

 

 加载3dtile代码如下:

 

    var tileset = new Cesium.Cesium3DTileset({ 
      url: "../../../static/3DModel/sicauOSM/tileset.json",

    }); 
    viewer.scene.primitives.add(tileset);
    console.log(tileset);

 

因为生成模型时候的问题,导致模型在地底下去了,调整模型位置代码如下:

    //3dtile加载完成后执行
    tileset.readyPromise.then(function(tileset) {
    
    //高度偏差,向上是正数,向下是负数
    var heightOffset = 500.0;

    //计算tileset的绑定范围
    var boundingSphere = tileset.boundingSphere;

    //计算中心点位置
    /**
     * fromCartesian 方法是用经纬度和高度定义一个位置
     * A position defined by longitude, latitude, and height.
     */
    var cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center);

    //计算中心点位置的地表坐标
    /**
     * Cartesian3 是一个3D点
     * fromRadians 方法 Returns a Cartesian3 position from longitude and latitude values given in radians(弧度).
     * @param longitude
     * @param latitude
     * @param height
     * 因为建筑模型没他所在高度信息,所以填0
     */
    var surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0);

    //偏移后的坐标,也就是中心点本应在的高度(海拔)    
    var offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, heightOffset);

    /**
     * subtract 方法 Computes the componentwise difference of two Cartesians.
     * 计算两个笛卡尔坐标的成分差异
     * @param 就是两个要计算的坐标
     * @param 第三个参数是要保存的结果
     */
    var translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3());

    console.log(`translation长这样:
    ${translation}`);
    // (-102.97917011496611, 417.3715669941157, 255.33559404686093)

    //tileset.modelMatrix转换
    /**
     * Creates a Matrix4 instance from a Cartesian3 representing the translation.
     * @param {Cartesian3} translation - The upper right portion of the matrix representing the translation.
     * @param {    Matrix4} result - The object in which the result will be stored, if undefined a new instance will be created.
     * Cesium中使用Matrix4作为处理线性变换和位移变换的仿射矩阵
     * 三维空间的转换矩阵通常是3x3的就可以
     * 但是为了同时满足位移的需要增加了一个维度使用4x4的矩阵
     */
    console.log(`变化前的tileset.modelMatrix为:
    ${tileset.modelMatrix}`);
    // (1, 0, 0, 0)
    // (0, 1, 0, 0)
    // (0, 0, 1, 0)
    // (0, 0, 0, 1)
    
    tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation);
    console.log(`变化后的tileset.modelMatrix为:
    ${tileset.modelMatrix}`);
    // (1, 0, 0, -102.97917011496611)
    // (0, 1, 0, 417.3715669941157)
    // (0, 0, 1, 255.33559404686093)
    // (0, 0, 0, 1)

    /**
     * 定位到3dtiles的位置,也就是让摄像头对准这个区域
     * viewBoundingSphere 方法
     * Sets the camera so that the current view contains the provided bounding sphere.
     * @param boundingSphere - The bounding sphere to view, in world coordinates.
     * @param offset  - The offset from the target in the local east-north-up reference frame centered at the target.
     */
    viewer.camera.viewBoundingSphere(tileset.boundingSphere, new Cesium.HeadingPitchRange(0, -20, 0));

    });

注意区分椭球坐标、笛卡尔坐标、屏幕坐标 

 我的第七篇文章讲了这些坐标的转换,需要的话链接:https://www.cnblogs.com/LJXXXX/p/17043938.html

 

 

posted @ 2023-01-05 13:58  一摩尔时光  阅读(1880)  评论(0编辑  收藏  举报