**
模型挖洞
**
一:技术原理:
模型挖洞通过面与模型的空间分析,确定挖洞区域模型;对于该部分模型,采用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。