ArcEngine 9.3 学习笔记(二):几何对象与空间参考(Envelope、Curve、TriangleScript、TriangleFan、Triangle、Ring、Multipatch Geometry集合接口)
2.4.5 Envelope几何对象
Envelope 是所有几何对象的外接矩形,用于表示几何对象的最小边框,所有几何对象都有一个Envelope对象;
通过IEnvelope接口可获取几何对象的XMax,XMin,YMax,YMin,Height,Width属性;IEnvelope的Expand方法,可按比例缩放Envelope对象的范围。
1 /// <summary> 2 /// 浏览Envelope对象的属性 3 /// </summary> 4 public void BrownIEnvelope() 5 { 6 IPolygon pPolygon = CreatePolygon(); 7 IEnvelope pEnvelope = pPolygon.Envelope; 8 9 double xMax = pEnvelope.XMax; 10 double xMin = pEnvelope.XMin; 11 double yMax = pEnvelope.YMax; 12 double yMin = pEnvelope.YMin; 13 double width = pEnvelope.Width; 14 double height = pEnvelope.Height; 15 16 pEnvelope.Expand(10.0, 5.0, true); 17 }
2.4.6 Curve对象
除去Point,MultiPoint和Envelope,其他所有几何体,都可以看做是Curve;
Line,Polyline,Polygon,CircularArc,BezierCurve,EllipticArc和CircularArc都是曲线的一种,都可QI到ICurve接口。
ICurve 属性、方法:
Length,返回一个Curve对象的长度
FromPoint和ToPoint属性,获取Curve对象的起止点
Reverseorientation 方法,改变Curve对象的节点次序,即将curve的方向改变,起始点和终止点互相调换
IsClosed,判断一个Curved对象是否闭合
GetSubcurve方法,可以截取一个Curve对象的一部分,pCurve.GetSubcurve(2,5,true, out pNewCurve); 例如,取pCurve的2-5千米处的曲线
QueryTangent和QueryNormal方法,用于获取Curve对象上某一点的曲线的切线和法线
1 /// <summary> 2 /// ICurve 接口的使用 3 /// </summary> 4 /// <param name="pPolyline"></param> 5 public void BrownICurve(IPolyline pPolyline) 6 { 7 // QI到ICurve接口 8 ICurve pCurve = pPolyline as ICurve; 9 // 创建一个Polyline对象 10 ICurve pNewCurve = new PolygonClass(); 11 bool btrue = true; 12 //获取2-5千米间的曲线对象 13 pCurve.GetSubcurve(2, 5, btrue, out pNewCurve); 14 }
2.4.7 TriangleScript和TriangleFan,Triangle,Ring几何对象
MultiPatch几何对象:可由TriangleScript, TriangleFan, Triangle 和 Ring对象组合构成。
1、TriangleStrip 对象是由一系列点定义的曲面片组成,而曲面片是由若干个三角形组成
2、TriangleFan 对象由一系列点定义的曲面片组成,所不同的是,所有的三角形共享一个顶点。
3、Triangle 对象(应该就叫曲面片),由三个点所确定,就是曲面片。
4、Ring和前边介绍的组成Polygon的Ring一样。
2.4.8 Multipatch 几何对象
Multipatch几何对象用于描述3D图形,可以由TriangleScript, TriangleFan, Triangle 和 Ring对象组合构成。Multipatch可以通过多种方式创建,一种是通过外部文件导入,另外AE提供了多种创建Multipatch几何对象的方法:
1、单纯的MultiPatch几何对象(不带贴图纹理、法向、组成部分信息),只需创建好组成Multipatch的各个部分即可,然后通过Multiple的IgeometryCollection接口添加各个组成部分;
2、如果要为Multipatch每个组成部分添加纹理、法向、组成部分信息等,就必须使用GeneralMultiPathCreator对象来创建,通过其IGeneralMultiPatchInfo接口来为MultiPatch各个组成部分定义法向、材质、属性信息。
3、通过IConstructMultiPatch接口和IExtrude接口操作GeometryEnvironment对象可以通过拉伸Polyline对象(拉伸为墙)和Polygon对象(拉伸为多面体)来创建MultiPatch。
4、通过访问3D 符号库,获取3DSymbol来渲染点,把三维符号放置在点的位置从而生成Multipatch。
接下来,通过GeneralMultiPatchCreator创建一个有纹理MultiPatch的方法:需要使用以下三个对象:
1、GeometryMaterial:用于构建材质,通过IGeometryMaterial创建的材质可以作为TextureLineSymbol或者TextureFillSymbol属性用来创建这些符号可以把它添加到GeometryMaterialList对象中,用于GeneralMultipatchCreator对象构建Multipatch对象。
2、GeometryMaterialList:材质对象的容器用于GeneralMultiPatchCreator对象调用Init方法时使用。
3、GeneralMultiPatchCreator:用于创建有纹理的贴图的MultiPatch。
以下代码片段演示如何创建一个MultiPatch对象:
1 /// <summary> 2 /// 构建Multipatc几何对象 3 /// a. 创建IGeometryMaterial图形材质对象,设置图片TextureImage 4 /// b. 将IGeometryMaterial图形材质对象 添加进IGeometryMaterialList材质列表 5 /// c. 创建GeneralMultiPatchCreator对象(用于创建有纹理材质的MultiPatch对象) 6 /// d. GeneralMultiPatchCreator对象的Init方法,可设置材质对象(IGeometryMaterialList) 7 /// e. 设置GeneralMultiPatchCreator对象的类型,环、三角扇等。。。,以及其他参数 8 /// f. 创建真实点和贴图点,然后设置到GeneralMultiPatchCreator对象中,通过索引来对应 9 /// g. GeneralMultiPatchCreator 调用CreateMultiPatch方法来创建MultiPatch对象 10 /// </summary> 11 /// <returns></returns> 12 public IMultiPatch CreateMultipatch() 13 { 14 try 15 { 16 // 创建图形材质对象 17 IGeometryMaterial texture = new GeometryMaterialClass(); 18 texture.TextureImage = @"d:\temp\img01.jgp"; 19 // 创建材质列表对象 20 IGeometryMaterialList materialList = new GeometryMaterialListClass(); 21 // 向材质列表添加材质 22 materialList.AddMaterial(texture); 23 // 创建GeneralMultiPatchCreator对象 24 IGeneralMultiPatchCreator multiPatchCreator = new GeneralMultiPatchCreatorClass(); 25 multiPatchCreator.Init(4, 1, false, false, false, 4, materialList); 26 // 设置Part:可以使用三角扇或环 27 multiPatchCreator.SetPatchType(0, esriPatchType.esriPatchTypeTriangleStrip); 28 multiPatchCreator.SetMaterialIndex(0, 0); 29 multiPatchCreator.SetPatchPointIndex(0, 0); 30 multiPatchCreator.SetPatchTexturePointIndex(0, 0); 31 // 创建真实points 32 WKSPointZ upperLeft = new WKSPointZ(); 33 WKSPointZ lowerLeft = new WKSPointZ(); 34 WKSPointZ upperRight = new WKSPointZ(); 35 WKSPointZ lowerRight = new WKSPointZ(); 36 upperLeft.X = 0; 37 upperLeft.Y = 0; 38 upperLeft.Z = 0; 39 40 upperRight.X = 300; 41 upperRight.Y = 0; 42 upperRight.Z = 0; 43 44 lowerLeft.X = 0; 45 lowerLeft.Y = 0; 46 lowerLeft.Z = -100; 47 48 lowerRight.X = 300; 49 lowerRight.Y = 1; 50 lowerRight.Z = -100; 51 52 multiPatchCreator.SetWKSPointZ(0, ref upperRight); 53 multiPatchCreator.SetWKSPointZ(1, ref lowerRight); 54 multiPatchCreator.SetWKSPointZ(2, ref upperLeft); 55 multiPatchCreator.SetWKSPointZ(3, ref upperRight); 56 // 设置贴图的点 57 WKSPoint textureUpperLeft = new WKSPoint(); 58 WKSPoint textureLowerLeft = new WKSPoint(); 59 WKSPoint textureUpperRight = new WKSPoint(); 60 WKSPoint textureLowerRight = new WKSPoint(); 61 62 textureUpperLeft.X = 0; 63 textureUpperLeft.Y = 0; 64 65 textureUpperRight.X = 1; 66 textureUpperRight.Y = 0; 67 68 textureLowerLeft.X = 0; 69 textureLowerLeft.Y = 1; 70 71 textureLowerRight.X = 1; 72 textureLowerRight.Y = 1; 73 74 multiPatchCreator.SetTextureWKSPoint(0, ref textureUpperRight); 75 multiPatchCreator.SetTextureWKSPoint(1, ref textureLowerRight); 76 multiPatchCreator.SetTextureWKSPoint(2, ref textureUpperLeft); 77 multiPatchCreator.SetTextureWKSPoint(3, ref textureLowerLeft); 78 79 // 创建MultiPatch对象 80 IMultiPatch multiPatch = multiPatchCreator.CreateMultiPatch() as IMultiPatch; 81 return multiPatch; 82 } 83 catch (Exception ex) 84 { 85 return null; 86 } 87 }
2.4.9 Geometry集合接口
除Point对象之外,其他几何对象都是通过其他几何对象几何构建而成:
1、MultiPoint 对象是点的集合 2、Path对象是Segment对象的集合
3、Polyline对象是Path对象的集合 4、Polygon对象是Ring对象的集合(Ring对象是Segment对象的集合,且Segment闭合)
5、Multipatch对象是TriangleStrip和TriagnleFan,Triangle,Ring对象的集合
AE提供了三个几何图形集合接口,用于对几何对象的操作:IPointCollection, ISegmentCollection, IGeometryCollection。
这些接口揭示出AE的几何模型实质----它们是一种组合构成的模式,这种组合并不一定按照严格的层次结构组织
2.4.9.1 IGeometryCollection 接口
IGeometryCollection接口被Polygon,polyline,Multipoint,Multipatch,triangle,triangleStrip,triangleFan和GeometryBag实现。
IGeometryCollection接口提供的方法,可以让开发者对一个几何对象的组成元素即子对象进行添加,改变和移除。
1 /// <summary> 2 /// 通过IGeometryCollection创建一个Polygon对象 3 /// </summary> 4 /// <param name="pRingList">Ring对象集合</param> 5 /// <returns></returns> 6 public IPolygon ConstructorPolygon(List<IRing> pRingList) 7 { 8 try 9 { 10 // 创建一个Polygon对象 11 IGeometryCollection pGeoCollection = new PolygonClass(); 12 object o = Type.Missing; 13 // 遍历Ring集合 14 for (int i = 0; i < pRingList.Count; i++) 15 { 16 // 向Polygon对象中添加Ring子对象 17 pGeoCollection.AddGeometry(pRingList[i] as IGeometry, ref o, ref o); 18 } 19 // QI至ITopologicalOperator ==> 确保添加子对象后的Polygon对象是有效的 20 ITopologicalOperator pTopological = pGeoCollection as ITopologicalOperator; 21 // 执行Simplify操作 ,防止出现子对象覆盖现象 22 pTopological.Simplify(); 23 IPolygon pPolygon = pGeoCollection as IPolygon; 24 return pPolygon; 25 } 26 catch (Exception) 27 { 28 return null; 29 } 30 }
同样,通过IGeometryCollection的AddGeometryCollection方法,可以将一个Polygon中的所有子对象Ring添加到另外一个多边形中。这样就实现了合并两个多边形对象为一个多边形的功能。
以下代码片段演示如何合并两个Polygon对象为一个Polygon对象:
1 /// <summary> 2 /// 合并两个Polygon 3 /// </summary> 4 /// <param name="firstPolygon"></param> 5 /// <param name="secondPolygon"></param> 6 /// <returns></returns> 7 public IPolygon MergePolygons(IPolygon firstPolygon, IPolygon secondPolygon) 8 { 9 try 10 { 11 // 创建一个Polygon对象 12 IGeometryCollection pGCollection1 = new PolygonClass(); 13 IGeometryCollection pGCollection2 = firstPolygon as IGeometryCollection; 14 IGeometryCollection pGCollection3 = secondPolygon as IGeometryCollection; 15 16 // 添加第一个多边形 17 pGCollection1.AddGeometryCollection(pGCollection2); 18 // 添加第二个多边形 19 pGCollection1.AddGeometryCollection(pGCollection3); 20 21 // QI 至 ITopologicalOperator 检测图形有效性 22 ITopologicalOperator pTopological = pGCollection1 as ITopologicalOperator; 23 // 执行Simplify操作 24 pTopological.Simplify(); 25 IPolygon pPolygon = pGCollection1 as IPolygon; 26 27 return pPolygon; 28 } 29 catch (Exception) 30 { 31 return null; 32 } 33 }
2.4.9.2 ISegmentCollection 接口
IsegmentCollection接口被Path,Ring,Polyline和Polygon四个类所实现;
ISegmentCollection接口的SetCircle和SetRectangle方法,提供了一种简单的,不需要添加Segment的情况下构建一个完整的Path,Ring,Polyline和Polygon的方法。
1 /// <summary> 2 /// 查看ISegmentCollection接口的属性、方法 3 /// </summary> 4 private void BrowseISegmentCollection() 5 { 6 ISegmentCollection pSegCollection = null; 7 // 指定圆心、半径创建圆形 8 pSegCollection.SetCircle(CreatePoint(100, 100), 150); 9 // 通过一个几何对象的外接矩形来创建矩形对象 10 pSegCollection.SetRectangle(CreateLine(CreatePoint(120, 120), CreatePoint(320, 123)).Envelope); 11 12 // 添加、插入、删除 13 //pSegCollection.AddSegment(... 14 //pSegCollection.InsertSegmentCollection(.. 15 //pSegCollection.InsertSegmentCollectionEx(.. 16 //pSegCollection.RemoveSegments(.. 17 }
2.4.9.3 IPointCollection 接口
IPointCollection 被 Mullipoint,Path,Ring,Polyline,Polygon,TriangleFan,TrangleScrip,Trangle,Multipatch等 实现。
通过IPointCollection接口定义的方法可以获取,添加、插入、查询、移除几何对象中的某个顶点。同以上两个接口一样,它也定义了操作一个点几何对象的方法,例如通过AddPoint方法可以向PointCollection对象中的特定索引位添加一个点对象,如果不指定位置,则添加到最后。通过IPointCollection的Point属性通过顶点索引可以得到某一顶点。
本章最后的Demo,会演示如何使用IPointCollection接口。
2.4.10 几何对象总结
在Geometry模型中的几何对象分为两种类型:
一类是用来直接构建要素类的称为高级几何对象,一类用来构建高级几何对象相对低一级的几何对象称为构建几何对象。