ArcGIS Engine開發之空間查詢


空間查詢功能是通過用戶選擇的空間幾何體以及該幾何體與當前地圖中要素之間的幾何關系進行空間查找,從而得到查詢結果的操作。

相關類與接口

空間查詢相關的類主要是SpatialFilter類,其實現的接口主要為ISpatialFilter接口。SpatialFilter類是空間關系過濾類,ISpatialFilter接口的成員主要用於返回和修改數據過濾器所使用的空間關系。ISpatialFilter接口同時包含了空間和屬性兩種查詢約束,它繼承了IQueryFilter接口。

1.Geometry屬性:

設置或獲取用來篩選數據的幾何體,其值為IGeometry接口類型。

2.GeometryField屬性:

獲取或設置應用於查詢過濾器中幾何字段的名稱。

3.SpatialRel屬性

獲取或設置過濾器所要使用的控件關系,其值為esriSpatialRelEnum枚舉類型,包括相交esriSpatialRelInersects、覆蓋esriSpatialRelOverlaps、跨越esriSpatialRelCrosses等多種空間關系。

 


實現思路:

通過ISpatialFilter接口定義空間查詢條件,其Geometry屬性確定用來查詢的空間幾何體,SpatialRel屬性定義查詢所使用的空間關系,為esriSpatialRelEnum枚舉類型的變量。包括:esriSpatialRelIntersects(空間相交)、esriSpatialRelTouches(空間相接,共享空間邊界),esriSpatialRelOverlaps(空間覆蓋)、esriSpatialRelCrosses(空間跨越)、esriSpatialRelWithin(空間被包含)、esriSpatialRelContains(空間包含)等。因為ISpatialFilter接口繼承與IQueryFilter接口,因此在定義好空間查詢條件后,可以使用IQueryFilter接口的查詢方法進行空間查詢操作。另外,在合並源圖層的幾何體時,使用ITopologicalOperator接口的Union方法來進行幾何體合並操作,該接口是點、線、面等幾何體對象所共同實現的接口。

 

代碼:

  1 public partial class FormQueryBySpatial : DevExpress.XtraEditors.XtraForm
  2     {
  3         //變量定義
  4         private IMap currentMap;//當前MapControl控件的Map對象
  5         private IFeatureLayer currentFeatureLayer;//設置臨時類變量來使用IFeatureLayer接口的當前圖層對象
  6         private string currentFileName;//設置臨時類變量來存儲字段名稱
  7         /// <summary>
  8         /// 獲得當前MapControl控件中的對象
  9         /// </summary>
 10         public IMap CurrentMap
 11         {
 12             set
 13             {
 14                 currentMap = value;
 15             }
 16         }
 17         public FormQueryBySpatial()
 18         {
 19             InitializeComponent();
 20         }
 21 
 22         private void FormQueryBySpatial_Load(object sender, EventArgs e)
 23         {
 24             //清空目標圖層列表
 25             checkListTargetLayer.Items.Clear();
 26             string layerName;//設置臨時變量存儲圖層名稱
 27             //對Map中的每一個圖層進行判斷並添加圖層名稱
 28             for (int i = 0; i < currentMap.LayerCount; i++)
 29             {
 30                 //如果該圖層為圖層組類型,則分別對所包含的每個圖層進行操作
 31                 if (currentMap.get_Layer(i) is GroupLayer)
 32                 {
 33                     //使用ICompositeLayer接口進行遍歷操作
 34                     ICompositeLayer compositeLayer = currentMap.get_Layer(i) as ICompositeLayer;
 35                     for (int j = 0; j < compositeLayer.Count; j++)
 36                     {
 37                         //將圖層的名稱添加到checkListTargetLayer控件中
 38                         layerName = compositeLayer.get_Layer(j).Name;
 39                         checkListTargetLayer.Items.Add(layerName);
 40                         comBoxSourceLayer.Items.Add(layerName);
 41                     }
 42                 }
 43                 //如果圖層不是圖層組類型,則直接添加名稱
 44                 else
 45                 {
 46                     layerName = currentMap.get_Layer(i).Name;
 47                     checkListTargetLayer.Items.Add(layerName);
 48                     comBoxSourceLayer.Items.Add(layerName);
 49                 }
 50             }
 51             //將comboxSourceLayer控件的默認選項設置為第一個圖層的名稱
 52             comBoxSourceLayer.SelectedIndex = 0;
 53             //將ComBoxMethod控件的默認選項設置為第一種控件選擇方法
 54             comBoxMethod.SelectedIndex = 0;
 55         }
 56 
 57 
 58         //定義方法獲取要素圖層
 59         private IFeatureLayer GetFeatureLayerByName(IMap map, string layerName)
 60         {
 61             //對地圖圖層進行遍歷
 62             for (int i = 0; i < map.LayerCount; i++)
 63             {
 64                 //如果該圖層為圖層組類型,則分別對包含的每個圖層進行操作
 65                 if (map.get_Layer(i) is GroupLayer)
 66                 {
 67                     //使用ICompositeLayer接口進行遍歷操作
 68                     ICompositeLayer compositeLayer = map.get_Layer(i) as ICompositeLayer;
 69                     for (int j = 0; j < compositeLayer.Count; j++)
 70                     {
 71                         //如果圖層名稱為所要查詢的圖層名稱,則返回IFeaturelayer接口的矢量圖層對象
 72                         if (compositeLayer.get_Layer(j).Name == layerName)
 73                         {
 74                             return (IFeatureLayer)compositeLayer.get_Layer(j);
 75                         }
 76                     }
 77                 }
 78                 //如果圖層不是圖層組類型,則直接進行判斷
 79                 else
 80                 {
 81                     if (map.get_Layer(i).Name == layerName)
 82                     {
 83                         return (IFeatureLayer)map.get_Layer(i);
 84                     }
 85                 }
 86             }
 87             return null;
 88         }
 89         //定義方法獲取幾何對象
 90         private IGeometry GetFeatureLayerGeometryUnion(IFeatureLayer featureLayer)
 91         {
 92             //定義IGeometry接口對象,存儲每一步拓撲操作后得到的幾何體
 93             IGeometry geometry = null;
 94             //使用ITopologicalOperator接口進行幾何體的拓撲操作
 95             ITopologicalOperator topologicalOperator;
 96             //使用null作為查詢過濾器得到圖層中所有要素的游標
 97             IFeatureCursor featureCursor = featureLayer.Search(null, false);
 98             //獲取IFeature接口游標中的第一個元素
 99             IFeature feature = featureCursor.NextFeature();
100             //當游標不為空時
101             while (feature != null)
102             {
103                 //如果幾何體不為空
104                 if (geometry != null)
105                 {
106                     //進行接口轉換,使當前接口進行拓撲操作
107                     topologicalOperator = geometry as ITopologicalOperator;
108                     //執行拓撲合並操作,將當前要素的幾何體與已有的幾何體進行Union,返回新的合並后的幾何體
109                     geometry = topologicalOperator.Union(feature.Shape);
110                 }
111                 else
112                     geometry = feature.Shape;
113                 feature = featureCursor.NextFeature();//移動游標到下一個要素
114             }
115             //返回最新合並的幾何體
116             return geometry;
117         }
118         //定義指定查詢的方法
119         private void SelectFeaturesBySpatial()
120         {
121             //定義和創建用於查詢的ISpatialFilter接口對象
122             ISpatialFilter spatialFilter = new SpatialFilterClass();
123             //默認設定用於查詢的空間幾何體為當前地圖源圖層中所有要素幾何體的集合
124             spatialFilter.Geometry = GetFeatureLayerGeometryUnion(GetFeatureLayerByName(currentMap, comBoxSourceLayer.SelectedItem.ToString()));
125             //根據對空間選擇方法的選擇采用相應的空間選擇方法
126             switch (comBoxMethod.SelectedIndex)
127             {
128                 case 0:
129                     spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
130                     break;
131                 case 1:
132                     spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelWithin;
133                     break;
134                 case 2:
135                     spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains;
136                     break;
137                 case 3:
138                     spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelTouches;
139                     break;
140                 case 4:
141                     spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelCrosses;
142                     break;
143                 case 5:
144                     spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelEnvelopeIntersects;
145                     break;
146                 case 6:
147                     spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelOverlaps;
148                     break;
149                 default:
150                     spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
151                     break;
152             }
153             //對選擇的目標圖層進行遍歷,並對每一個圖層進行空間查詢,查詢結果將放在選擇集中
154             IFeatureLayer featureLayer;
155             //對所有選擇的目標圖層進行遍歷
156             for (int i = 0; i < checkListTargetLayer.CheckedItems.Count; i++)
157             {
158                 //根據選擇的目標圖層名稱獲得對應的矢量圖層
159                 featureLayer = GetFeatureLayerByName(currentMap, (string)checkListTargetLayer.CheckedItems[i]);
160                 //進行接口轉換,使用IFeatureSelection接口選擇要素
161                 IFeatureSelection featureSelection = featureLayer as IFeatureSelection;
162                 //使用IFeatureSelection接口的SelectFeature方法,根據空間查詢過濾器選擇要素,將其放在新的選擇集中
163                 featureSelection.SelectFeatures((IQueryFilter)spatialFilter, esriSelectionResultEnum.esriSelectionResultAdd, false);
164             }
165             //進行接口轉換,使用IActiveView接口進行視圖操作
166             IActiveView activeView = currentMap as IActiveView;
167             //進行部分刷新操作,只刷新選擇集的內容
168             activeView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, activeView.Extent);
169         }
170 
171         private void btnOk_Click(object sender, EventArgs e)
172         {
173             try
174             {
175                 SelectFeaturesBySpatial();
176                 this.Close();
177             }
178             catch { }
179         }
180 
181         private void btnApply_Click(object sender, EventArgs e)
182         {
183             try
184             {
185                 SelectFeaturesBySpatial();
186             }
187             catch { }
188         }
189 
190         private void btnClose_Click(object sender, EventArgs e)
191         {
192             this.Close();
193         }
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM