空間查詢功能是通過用戶選擇的空間幾何體以及該幾何體與當前地圖中要素之間的幾何關系進行空間查找,從而得到查詢結果的操作。
相關類與接口
空間查詢相關的類主要是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 }