3d模板源码-C2——cesium加载城市级三维管网模型的方案

**本文档及路线由“”本人创作,禁止抄袭。

目的是感谢“蚂蚁管道”的盛哥提供免费软件,希望有能力的兄弟能够与他合作。

本文档可以针对整个城区的管点和管道,实现shp官网数据的数据生成生成3D obj然后传输到3Dtiles,最后在Cesium上加载显示。 另外,“ant pipeline”生成的obj可以直接在3Dmax中查看。

我们先来看效果图:下图包括:(绿色)雨水; (紫色)污水; (棕色)雨水和污水汇合处; 综合管道等。双击查看属性,鼠标悬停查看ID。管网shp数据达到2G,最终模型6G左右。

/*************************分向線********************** **********/

具体步骤:

第一步:准备shp文件。 和 Ant Pipeline 软件。 shp 文件应该有相关字段。 具体可以参考Ant Pipeline的帮助文档。 如果还有不明白的可以私信我或者问盛哥。 软件直接到“盛哥QQ:441224629.邮箱:sgeoffrey@qq.com”申请或购买。

3d模板源码_3d模型源码_源码模板网

特别注意:如果shp数据太大,一次运行就会失败。 我用ARCGIS把城市的shp切割成十多分钟,分别生成obj模型。 如何进行下一步。

第二步:由于管道数据在市内属于保密3d模板源码,因此不再贴出地图。

shp切割arcgis加载城市的shp文件,创建一个表面来框住所有管点和管道,并将编辑表面切割成几个小块。 每个小片的最大行数据约为10000条。 如果太多,可能会引起问题。 在此过程中软件崩溃。

然后选择一个小块,按位置选择,选择小块内的所有管点和管道。

使用arcgis的“要素类到shp批量”工具将块范围内的所有管道点和管道导出为shp1。 等等...

3d模型源码_3d模板源码_源码模板网

步骤3:使用Ant Pipeline为管道点的各个部分生成obj模型。

注意:在生成的最后一步,需要检查基于地理位置的建模,以便每个obj最终都能保持其相对位置。 至于自己调整颜色,有文档(最终的模型属性带有自己的ID和文件名,但不包含属性,需要关联数据库进行查询)

完成的obj可以直接用3dmax打开查看3d模板源码,也可以转成其他格式。最好用Ant Pipeline自带的查看器打开

第 4 步:使用 cesiumlab 一次性从所有 obj 生成 3Dtile。

第5步:cesium加载3Dtiles。 (上面我的3Dtiles的位置不能选择,否则会失败。但是你可以在cesium中自己确定坐标,这是最好的)

贴出代码:

let pipeDazu1 = this.viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
    url: "../src/data/3Dtiles/pipedazu1/tileset.json",
    skipLevelOfDetail: true, //开启跳级加载
    maximumMemoryUsage: 2000, //最大内存占用  推荐显存的一般
    preferLeaves: true,
    maximumScreenSpaceError: 16,
    // maximumNumberOfLoadedTiles: 2000,
  })
);
pipeDazu1.readyPromise.then(function (argument) {
    let rotationX = Cesium.Matrix4.fromRotationTranslation(Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(0)));
    let rotationY = Cesium.Matrix4.fromRotationTranslation(Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(0)));
    let rotationZ = Cesium.Matrix4.fromRotationTranslation(Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(0)));
    let m = Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(1**.73427380132752, 2*.687039062817977, 245));
    //旋转、平移矩阵相乘
    Cesium.Matrix4.multiply(m, rotationX, m);
    Cesium.Matrix4.multiply(m, rotationY, m);
    Cesium.Matrix4.multiply(m, rotationZ, m);
    pipeDazu1._root.transform = m;
});

步骤6:关联视图属性。 ajax请求的逻辑因后端和数据库的不同而不同。 你可以自己选择。

pickFeature.getProperty('file') 这获取文件名。 我的文件名对应数据表名,例如:雨水管‘污水管点’

pickFeature.getProperty('id').split('_')[3]:获取ID,该ID对应于查询条件。

// 管网3dtiles 选中及属性检测***********************************************
// 组装弹窗元素
let nameOverlay = document.createElement('div');
viewer.container.appendChild(nameOverlay);
nameOverlay.className = 'backdrop';
nameOverlay.style.display = 'none';
nameOverlay.style.position = 'absolute';
nameOverlay.style.bottom = '0';
nameOverlay.style.left = '0';
nameOverlay.style['pointer-events'] = 'none';
nameOverlay.style.padding = '4px';
nameOverlay.style.backgroundColor = 'yellowgreen';
/*鼠标移动选择管线*/
let selected = {
    feature: undefined,
    originalColor: new Cesium.Color()
};
let highlighted = {
    feature: undefined,
    originalColor: new Cesium.Color()
};
let selectedEntity = new Cesium.Entity();
let clickHandler = viewer.screenSpaceEventHandler.getInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
/*左键双击显示查看管线属性*/
viewer.screenSpaceEventHandler.setInputAction(function onLeftClick(movement) {
    if (Cesium.defined(selected.feature)) {
        selected.feature.color = selected.originalColor;
        selected.feature = undefined;
    }
    let pickedFeature = viewer.scene.pick(movement.position);
    if (!Cesium.defined(pickedFeature) || !Cesium.defined(pickedFeature.getProperty)) {
        return;
    }
    if (selected.feature === pickedFeature) {
        return;
    }
    selected.feature = pickedFeature;
    if (pickedFeature === highlighted.feature) {
        Cesium.Color.clone(highlighted.originalColor, selected.originalColor);
        highlighted.feature = undefined;
    } else {
        Cesium.Color.clone(pickedFeature.color, selected.originalColor);
    }
    pickedFeature.color = Cesium.Color.fromCssColorString('#0000FF');
    if (pickedFeature.getProperty('file')) {//查询文件对应导数据库里边的tablename
        $.ajax({
            type: "GET",
            url: "/guanwang/" + pickedFeature.getProperty('file') + "/" + pickedFeature.getProperty('id').split('_')[3],
            success: function (data) {
                let str = '';
                for (let key in data) {
                    str += '';
                }
                str += '
' + _this.fieldsConversion(key) + '' + data[key] + '
'; if ($('#popup').is(':visible')) {  //如果node是显示的则隐藏node元素,否则显示 $('#popup').css("display", "none") } $("#popup-container").html(str); $('#popup').css("left", "20%") $('#popup').fadeIn(300); }, error: function (data) { console.log("Error: " + data.status); } }); } }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);

你完成了! ! ! 这波操作应该是比较顺利的。 技术路线是我想了很久,尝试了很多方法才搞定的。请勿抄袭,转载明确注明原始出处:cesium城市级管网加载攻略

补充:主要是我使用时遇到的问题

1:生成的模型末尾部分虚线丢失。 这是怎么做的! 。

原因:shp数据中管道点的id与管道的id不匹配。

3d模板源码_3d模型源码_源码模板网

处理:修改id。 最好检查一下shp属性表,确保ids都正确,高程是否为0,管径是否异常。

另一个技巧:例如,我的管道 ID 是 00YS345 和 00WS786。 中间可能有一些应该是00YS*,写成00WS。 在arcgis属性表中,“字段计算器”中选择python,运行以下代码:field name.replace('WS','YS'); 好的!

2:上面提到了软件运行中途崩溃的问题。 再次打开并运行剩下的文件,最后发现后面生成的文件和前面的文件顺序乱了! ! ! 是不是很烦人。 多么破碎啊! ! !

列出我想到的解决方案:

场景假设:由于shp文件太大,所以将shp分为5个文件12345。当依次运行1234到第4个时,软件自动崩溃。 再次打开运行文件 45。 45和123生成的obj坐标原点不对应。 最后,它们在铯中叠加在一起。

方法一:使用obj123执行上面第四步生成3Dtiles1; 使用obj45执行上面第四步生成3Dtiles2。 分别在 cesium 中加载两个 3Dtile。 这种方法的问题是需要同时操作两个数据,并且指定两个瓦片的位置比较麻烦。

方法二:软件崩溃后,打开软件再次执行shp1,然后执行4和5。这样可以保证后面生成的45和前面的123是同一个坐标原点。 推荐推荐!