Flyingis

          Talking and thinking freely !
          Flying in the world of GIS !
          隨筆 - 156, 文章 - 16, 評論 - 589, 引用 - 0
          數據加載中……

          Geometry 對象淺析

              作者:Flyingis

              ArcEngine Geometry庫定義了基本幾何圖形的矢量表達形式,頂級的幾何圖形有Points、Multipoints、Polylines、Polygons、Multipatches,Geodatabase和繪圖系統使用這些幾何圖形來定義其他各種形狀的特征和圖形,提供了編輯圖形的操作方法和地圖符號系統符號化特征數據的途徑。

              Geometry庫中幾個核心類和接口構成了Geometry對象的基本框架。

              GeometryEnvironment

              GeometryEnvironment提供了從不同的輸入、設置或獲取全局變量來創建幾何圖形的方法,以便控制geometry方法的行為。GeometryEnvironment對象是一個單例對象。
          public IPolyline TestGeometryEnvironment()
          {
              ISpatialReferenceFactory spatialReferenceFactory 
          = new SpatialReferenceEnvironmentClass();

              
          //Create a projected coordinate system and define its domain, resolution, and x,y tolerance.
              ISpatialReferenceResolution spatialReferenceResolution = spatialReferenceFactory.CreateProjectedCoordinateSystem((int)esriSRProjCSType.esriSRProjCS_NAD1983UTM_11N) as ISpatialReferenceResolution;
              spatialReferenceResolution.ConstructFromHorizon();
              ISpatialReferenceTolerance spatialReferenceTolerance 
          = spatialReferenceResolution as ISpatialReferenceTolerance;
              spatialReferenceTolerance.SetDefaultXYTolerance();
              ISpatialReference spatialReference 
          = spatialReferenceResolution as ISpatialReference;

              
          //Create an array of WKSPoint structures starting in the middle of the x,y domain of the 
              
          //projected coordinate system.

              
          double xMin;
              
          double xMax;
              
          double yMin;
              
          double yMax;
              spatialReference.GetDomain(
          out xMin, out xMax, out yMin, out yMax);

              
          double xFactor = (xMin + xMax) * 0.5;
              
          double yFactor = (yMin + yMax) * 0.5;

              WKSPoint[] wksPoints 
          = new WKSPoint[10];
              
          for (int i = 0; i < wksPoints.Length; i++)
              
          {
                  wksPoints[i].X 
          = xFactor + i;
                  wksPoints[i].Y 
          = yFactor + i;
              }


              IPointCollection4 pointCollection 
          = new PolylineClass();

              IGeometryBridge2 geometryBridge 
          = new GeometryEnvironmentClass();
              geometryBridge.AddWKSPoints(pointCollection, 
          ref wksPoints);

              IPolyline polyline 
          = pointCollection as IPolyline;
              polyline.SpatialReference 
          = spatialReference;

              
          return polyline;
          }

              new GeometryEnvironmentClass僅僅是創建了一個指向已存在的GeometryEnvironmentClass的引用。注意IGeometryBridge2接口的使用,addWKSPoints方法將WKSPoint二維點添加到PointCollection中,用于構建path、ring、polyline、polygon,或增加新點到Multipoint、TriangleFan、TriangleStrip。在Geometry庫中,除了IGeometryBridge2還有IGeometryBridge接口,后者繼承了前者,增加了一些編輯功能(添加點、插入點、重置點、分段等)。

              GeometryBag

              GeometryBag是支持IGeometry接口的幾何對象引用的集合,任何幾何對象都可以通過IGeometryCollection接口添加到GeometryBag中,但是在使用拓撲操作的時候,需要注意不同類型的幾何類型可能會有相互不兼容的情況。在向GeometryBag中添加幾何對象的時候,GeometryBag對象需要指定空間參考,添加到其中的幾何對象均擁有和GeometryBag對象一樣的空間參考。
          private IPolygon GeometryBag_Example(IFeatureClass featureClass)
          {

              
          //Check input objects.
              if (featureClass == null)
              
          {
                  
          return null;
              }


              IGeoDataset geoDataset 
          = featureClass as IGeoDataset;
              ISpatialFilter queryFilter 
          = new SpatialFilterClass();

              
          //Set the properties of the spatial filter here.
              IGeometry geometryBag = new GeometryBagClass();

              
          //Define the spatial reference of the bag before adding geometries to it.
              geometryBag.SpatialReference = geoDataset.SpatialReference;

              
          //Use a nonrecycling cursor so each returned geometry is a separate object. 
              IFeatureCursor featureCursor = featureClass.Search(queryFilter, false);

              IGeometryCollection geometryCollection 
          = geometryBag as IGeometryCollection;
              IFeature currentFeature 
          = featureCursor.NextFeature();

              
          while (currentFeature != null)
              
          {
                  
          //Add a reference to this feature's geometry into the bag.
                  
          //You don't specify the before or after geometry (missing),
                  
          //so the currentFeature.Shape IGeometry is added to the end of the geometryCollection.
                  object missing = Type.Missing;
                  geometryCollection.AddGeometry(currentFeature.Shape, 
          ref missing, ref missing);

                  currentFeature 
          = featureCursor.NextFeature();
              }


              
          // Create the polygon that will be the union of the features returned from the search cursor.
              
          // The spatial reference of this feature does not need to be set ahead of time. The 
              
          // ConstructUnion method defines the constructed polygon's spatial reference to be the same as 
              
          // the input geometry bag.
              ITopologicalOperator unionedPolygon = new PolygonClass();
              unionedPolygon.ConstructUnion(geometryBag 
          as IEnumGeometry);

              
          return unionedPolygon as IPolygon;
          }


              Points

              一個點包括X、Y坐標,同時可以增加M、Z值及ID屬性來擴展點的功能。

              Multipoints

              點的集合,多點組成Multipoint幾何類型,使用multipoint對象實現了的IPointCollection接口可以訪問所有的點元素,這些點同樣可以擁有M、Z值及ID屬性來獲得更多的地理空間內涵。

              下面列舉一個例子,通過一個已知的polyline來定義一個新的multipart polyline。

          public IPolyline ConstructMultiPartPolyline(IPolyline inputPolyline)
          {
              IGeometry outGeometry 
          = new PolylineClass();

              
          //Always associate new, top-level geometries with an appropriate spatial reference.
              outGeometry.SpatialReference = inputPolyline.SpatialReference; 
           
              IGeometryCollection geometryCollection 
          = outGeometry as IGeometryCollection;

              ISegmentCollection segmentCollection 
          = inputPolyline as ISegmentCollection;

              
          //Iterate over existing polyline segments using a segment enumerator.
              IEnumSegment segments = segmentCollection.EnumSegments;

              ISegment currentSegment;
              
          int partIndex = 0;;
              
          int segmentIndex = 0;;  
              segments.Next(
          out currentSegment,ref partIndex, ref segmentIndex);
              
          while(currentSegment != null)
              
          {
                  ILine normal 
          = new LineClass();

                  
          //Geometry methods with _Query_ in their name expect to modify existing geometries. 
                  
          //In this case, the QueryNormal method modifies an existing line
                  
          //segment (normal) to be the normal vector to 
                  
          //currentSegment at the specified location along currentSegment.
                  currentSegment.QueryNormal(esriSegmentExtension.esriNoExtension, 0.5true, currentSegment.Length / 3, normal); 
           
                  
          //Since each normal vector is not connected to others, create a new path for each one.
                  ISegmentCollection newPath = new PathClass();
                  
          object missing = Type.Missing;
                  newPath.AddSegment(normal 
          as ISegment, ref missing, ref missing);
                  
          //The spatial reference associated with geometryCollection will be assigned to all incoming paths and segments.
                  geometryCollection.AddGeometry(newPath as IGeometry, ref missing, ref missing);

                  segments.Next(
          out currentSegment,ref partIndex, ref segmentIndex);
              }

              
          //The geometryCollection now contains the new, multipart polyline.
              return geometryCollection as IPolyline;
          }


              ISegment接口的QueryNormal方法用來在弧段上的某一點生成該弧段的法線,指定其長度,這樣就生成了新的segment,并且多個path添加到geometryCollection中,以IPolyline的形式返回。

              Polylines

              Polylines是有序path組成的集合,可以擁有M、Z和ID屬性值。Polyline對象的IPointCollection接口包含了所有節點的復制,IGeometryCollection接口可以獲取polyline的paths,ISegmentCollection接口可以獲取polyline的segments。

              Polyline結構圖

              Polygons

              Polygon是一系列rings組成的集合,可以擁有M、Z和ID屬性值。每一個ring由一個或多個segment組成,Polygon或ring對象的IPointCollection接口包含了所有節點的復制,IGeometryCollection接口可以獲取polygon的rings,ISegmentCollection接口可以獲取polygon的segments。

              Polygon結構圖


              Multipatch

              Multipatch用于描述3D面狀幾何類型,由一系列的矢量三角形構成,如果其中的part是一個ring,那么它必須是封閉的,第一個節點和最后一個節點相同,另外每個part所包含節點的順序非常重要,Inner Rings在Outer Rings之后,代表單個表面patch的一系列rings必須由第一個ring開始。


              在9.0以后的開發包中,使用IGeneralMultiPatchCreator創建新的Multipatch,IGeometryMaterial進行材質貼圖。

          public IMultiPatch CreateMultipatch()
          {
              
          //Prepare the geometry material list.
              IGeometryMaterial texture = new GeometryMaterialClass();
              texture.TextureImage 
          = "C:\\Temp\\MyImage.bmp";

              IGeometryMaterialList materialList 
          = new GeometryMaterialListClass();
              materialList.AddMaterial(texture);

              
          //Create the multipatch.
              IGeneralMultiPatchCreator multiPatchCreator = new GeneralMultiPatchCreatorClass();
              multiPatchCreator.Init(
          41falsefalsefalse4, materialList);

              
          //Set up part.

              
          //Could also use a Ring or a TriangleFan.
              multiPatchCreator.SetPatchType(0, esriPatchType.esriPatchTypeTriangleStrip);
              multiPatchCreator.SetMaterialIndex(
          00);
              multiPatchCreator.SetPatchPointIndex(
          00);
              multiPatchCreator.SetPatchTexturePointIndex(
          00);

              
          //Set real-world points.
              WKSPointZ upperLeft  = new WKSPointZ();
              WKSPointZ lowerLeft  
          = new WKSPointZ();
              WKSPointZ upperRight 
          = new WKSPointZ();
              WKSPointZ lowerRight 
          = new WKSPointZ();

              upperLeft.X 
          = 0;
              upperLeft.Y 
          = 0;
              upperLeft.Z 
          = 0;
              upperRight.X 
          = 300;
              upperRight.Y 
          = 0;
              upperRight.Z 
          = 0;
              lowerLeft.X 
          = 0;
              lowerLeft.Y 
          = 0;
              lowerLeft.Z 
          = -100;
              lowerRight.X 
          = 300;
              lowerRight.Y 
          = 1;
              lowerRight.Z 
          = -100;

              multiPatchCreator.SetWKSPointZ(
          0ref upperRight);
              multiPatchCreator.SetWKSPointZ(
          1ref lowerRight);
              multiPatchCreator.SetWKSPointZ(
          2ref upperLeft);
              multiPatchCreator.SetWKSPointZ(
          3ref lowerLeft);

              
          //Set texture points.
              
          //Set the texture coordinates for a panel.
              WKSPoint textureUpperLeft  = new WKSPoint();
              WKSPoint textureLowerLeft  
          = new WKSPoint();
              WKSPoint textureUpperRight 
          = new WKSPoint();
              WKSPoint textureLowerRight 
          = new WKSPoint();

              textureUpperLeft.X 
          = 0;
              textureUpperLeft.Y 
          = 0;
              textureUpperRight.X 
          = 1;
              textureUpperRight.Y 
          = 0;
              textureLowerLeft.X 
          = 0;
              textureLowerLeft.Y 
          = 1;
              textureLowerRight.X 
          = 1;
              textureLowerRight.Y 
          = 1;

              multiPatchCreator.SetTextureWKSPoint(
          0ref textureUpperRight);
              multiPatchCreator.SetTextureWKSPoint(
          1ref textureLowerRight);
              multiPatchCreator.SetTextureWKSPoint(
          2ref textureUpperLeft);
              multiPatchCreator.SetTextureWKSPoint(
          3ref textureLowerLeft);
              IMultiPatch multiPatch 
          = multiPatchCreator.CreateMultiPatch() as IMultiPatch;

              
          return multiPatch;
          }

              參考資料:ArcEngine 9.2幫助文檔

          posted on 2007-04-19 14:15 Flyingis 閱讀(4934) 評論(4)  編輯  收藏 所屬分類: ArcEngine

          評論

          # re: Geometry 對象淺析  回復  更多評論   

          謝lz
          2007-11-12 23:05 | jokocox@gmail.com

          # re: Geometry 對象淺析  回復  更多評論   

          寫得不怎么樣,希望把英語好好學習一下,不信您自己再看看文檔
          2008-03-05 12:09 | o(∩_∩)o...

          # re: Geometry 對象淺析  回復  更多評論   

          @o(∩_∩)o...

          時間有限,寫的比較匆忙,有問題的地方請指正。
          2008-03-11 11:37 | Flyingis

          # re: Geometry 對象淺析  回復  更多評論   

          正在弄一些小困助程序,被這些Segment、ring搞懵了,謝謝你的文章。
          2009-02-25 13:37 | 風雨中
          主站蜘蛛池模板: 石首市| 简阳市| 荣成市| 双鸭山市| 台州市| 巴彦淖尔市| 镶黄旗| 宜州市| 阿瓦提县| 鹤山市| 阿克| 邢台市| 余干县| 平罗县| 乡宁县| 上栗县| 汶川县| 深圳市| 旬邑县| 屏边| 沧州市| 秦皇岛市| 锡林郭勒盟| 嫩江县| 溧水县| 和林格尔县| 喀什市| 邵武市| 乌恰县| 红原县| 准格尔旗| 修文县| 什邡市| 清河县| 诸城市| 五家渠市| 霍邱县| 新干县| 水富县| 达尔| 西贡区|