【二次开发】CityMaker常见分析——模型挖洞

本文详细介绍了模型挖洞技术的实现原理与步骤,包括绘制挖洞面、进行空间查询及模型切割。通过.NET与JS代码示例,展示了如何在相交模型上应用此技术,并提供了注意事项,如面闭合与模型数据支持。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

**

模型挖洞

**

一:技术原理:

模型挖洞通过面与模型的空间分析,确定挖洞区域模型;对于该部分模型,采用IGeometryConvertor接口,切割与面相交的模型。
模型挖洞主要分为三步:绘制挖洞面,进行空间查询,依次对相交模型进行切割。
在这里插入图片描述

二:实现模型挖洞:

1. .Net代码

private void modelpointanalysis() 
{   
    AxRenderControl rendercontrol=getRenderControl();//获取控件
    IGeometryFactory geoFactory = new GeometryFactory();
    IPolygon tarPolygon= geoFactory.CreateGeometry(gviGeometryType.gviGeometryPolygon, gviVertexAttribute.gviVertexAttributeZ) as IPolygon;

    ...省略tarPolygon范围值部分...

    //空间查询
    ISpatialFilter filter = new SpatialFilterClass();
    filter.Geometry = tarPolygon;
    filter.SpatialRel = gviSpatialRel.gviSpatialRelEnvelope; //包围盒相交
    filter.GeometryField = "Geometry";
    cursor = fc.Search(filter, false);//在某一要素类中进行查询

    //依次对相交模型进行切割
    while ((row = cursor.NextRow()) != null)
    {
        int oid = (int)row.GetValue(0);
        rendercontrol.FeatureManager.SetFeatureVisibleMask(fc, oid, gviViewportMask.gviViewNone);//隐藏相交对象

        int geoPos = row.FieldIndex("Geometry");
        IModelPoint mp = row.GetValue(geoPos) as IModelPoint;//获取模型点
        IMultiPolygon mPolygon = geoFactory.CreateGeometry(gviGeometryType.gviGeometryMultiPolygon, gviVertexAttribute.gviVertexAttributeZ) as IMultiPolygon;
        mPolygon.AddGeometry(tarPolygon);

        IResourceManager rm = fc.FeatureDataSet as IResourceManager;
        IModel model = rm.GetModel(mp.ModelName);//获取模型
        IModel modelInterior = null;
        IModelPoint mpInterior = null;
        IModel modelExterior = null;
        IModelPoint mpExterior = null;
        IGeometryConvertor geoConvertor = new GeometryConvertor();
        geoConvertor.SplitModelPointByPolygon2D(mPolygon, model, mp, out modelInterior, out mpInterior, out modelExterior, out mpExterior);//用面对模型和模型店进行切割


        if (modelExterior != null)
        {
            rendercontrol.ObjectManager.AddModel(fc.Name + oid + "Exterior", modelExterior);
            mpExterior.ModelName = fc.Name + oid + "Exterior";

            string[] imagenames = modelExterior.GetImageNames();
            for (int j = 0; j < imagenames.Length; j++)
            {
                IImage image = rm.GetImage(imagenames[j]);
                rendercontrol.ObjectManager.AddImage(imagenames[j], image);
            }
            IRenderModelPoint rrrr = rendercontrol.ObjectManager.CreateRenderModelPoint(mpExterior, null, rootId); //补齐模型
        }                        
    }
}

2. JS代码

function modelpointanalysis()
{
    var __g=document.getElementById("__g");//获取控件
    var geoFactory=__g.geometryFactory;
    var currentGeometry= geoFactory.CreateGeometry(gviGeometryType.gviGeometryPolygon, gviVertexAttribute.gviVertexAttributeZ);

    ...省略currentGeometry范围值部分...

     //空间查询
    var spatialFilter = __g.new_SpatialFilter;
    spatialFilter.geometry = currentGeometry;
    spatialFilter.spatialRel = gviSpatialRel.gviSpatialRelEnvelope;   //包围盒相交
    spatialFilter.geometryField = "Geometry";
    var cursor = fc.search(spatialFilter, false);//在某一要素类中进行查询

    var modelRow = null;
    var multiPolygon = __g.geometryFactory.createGeometry(gviGeometryType.gviGeometryMultiPolygon, gviVertexAttribute.gviVertexAttributeZ);
    multiPolygon.addPolygon(currentGeometry);

     //依次对相交模型进行切割
    while ((modelRow = cursor.nextRow()) != null) {
        var modelOid = modelRow.getValue(modelRow.fieldIndex("oid"));
        __g.featureManager.setFeatureVisibleMask(searchFc, modelOid, gviViewportMask.gviViewNone);//隐藏相交对象
        var modelPnt = modelRow.getValue(modelRow.fieldIndex("Geometry"));//获取模型点
        var model = fc.featureDataSet.getModel(modelPnt.modelName);//获取模型
        var    splitResult = __g.geometryConvertor.splitModelPointByPolygon2D(multiPolygon, model, modelPnt);//用面对模型和模型店进行切割

        if (splitResult["modelExterior"] != null) {
            __g.objectManager.addModel(fc.name + modelOid + "Exterior", splitResult["modelExterior"]);
            splitResult["modelPointExterior"].modelName = fc.name + modelOid + "Exterior";

            var imagenames = splitResult["modelExterior"].getImageNames();
            for (var k = 0; k < imagenames.length; k++) {
                var image = fc.featureDataSet.getImage(imagenames[k]);
                __g.objectManager.addImage(imagenames[k], image);
            }
            var splitModel = __g.objectManager.createRenderModelPoint(splitResult["modelPointExterior"], null, __rootId);//补齐模型
        }
    }
}

三:注意事项

1、模型挖洞仅支持模型数据。
2、挖洞面必须闭合,推荐在挖洞前调用close方法手动闭合。
3、面与模型相交部分采用了模型切割方法splitModelPointByPolygon2D,该方法在.NET和JS代码中有不同的返回值使用方法,请使用者注意。
4、切割面可以设置切割高度,具体方法如下:
在这里插入图片描述5、更多示例请参考SDK中级篇TileHole。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值