這兩天幫網上認識的一個兄弟做了一個查詢的示例,多多少少總結一下,在此和大家分享。
為什么說是復合多條件呢?因為進行空間查詢有時候我們查詢的條件會很復雜,比如要求某一要素的某一屬性大於多少,且小於多少,且又不等於多少等等。而在官網給出的例子中並沒有關於復合查詢的說明。不過查看API后,你會發現一句很重要的話:
A where clause for the query. Any legal SQL where clause operating on the fields in the layer is allowed, for example: where=POP2000 > 350000.
也就是說在進行空間查詢是Query的Where屬性實際上是SQL where查詢的字符串,所以這樣我們寫查詢條件是就可以仿照SQL where查詢語句的方式。具體可參考如下的示例。
一、前台部分
界面設計如下:
前台XAML代碼如下:
MainPage.xaml

說明:
在前台頁面還增加了要素的Web在線編輯功能,如果要素來自於ArcSDE數據庫,那么還可以同步跟新到后台的數據庫。
二、后台代碼
后台主要是實現查詢,查詢時通過QueryTask指定查詢的圖層以及聲明查詢的任務,QueryTask通過ExecuteAsync方法接收Query參數,然后開始查詢,通過QueryCompleted事件返回查詢的結果。
其中Query指定查詢的條件和查詢相關的參數,下面列出了Query的常用參數列表:
參數列表 | 參數說明 |
Geometry | 指定查詢的空間過濾器,並可通過Query.SpatialRelationship來描述查詢的空間關系,有效的幾何類型有:MapPoint, Polyline, Polygon, Envelope, or MultiPoint. |
OutFields | 篩選的字段集合即要素包含的屬性 |
ReturnGeometry | 返回查詢的幾何要素,如果返回全部字段,則強制設置了ReturnGeometry為true |
Source | 如果查詢的是動態圖層,這設置圖層源 |
SpatialRelationship | 描述空間查詢被查詢的要素與輸入的幾何要素的空間關系 |
Text | 對應要素服務圖層中顯示的字段 |
Where | 查詢語句,由一條合法的SQL語句表示 |
下面看一下查詢具體實現的方式:
首先聲明QueryTask及查詢的目標圖層
//用於查詢的Task QueryTask queryTask = new QueryTask(); //查詢的目標圖層 FeatureLayer featurelayer;
//聲明一個Draw,用於繪制查詢的區域,進行空間查詢
Draw myDraw;
在構造函數中賦值和實例化
public MainPage() { InitializeComponent(); featurelayer = map1.Layers["RiverSourceLayer"] as FeatureLayer; editorWidget.Loaded += new RoutedEventHandler(editorWidget_Loaded); queryTask.Url = featurelayer.Url; queryTask.ExecuteCompleted += new EventHandler<QueryEventArgs>(queryTask_ExecuteCompleted); queryTask.Failed += new EventHandler<TaskFailedEventArgs>(queryTask_Failed);
myDraw = new Draw(map1);
myDraw.DrawMode = DrawMode.Polygon;
myDraw.IsEnabled = false;
myDraw.FillSymbol = new SimpleFillSymbol()
{
BorderBrush=new SolidColorBrush(Colors.Black),
BorderThickness=3,
Fill=new SolidColorBrush (Colors.Red),
};
myDraw.DrawComplete += new EventHandler<DrawEventArgs>(myDraw_DrawComplete);
FiledsCombox.ItemsSource = AttributeString.GraphicAttributesEnNameString; }
自定義兩個查詢方法:
StartQueryBySQL(string sqlString):按SQL 的Where語句進行查詢。
private void StartQueryBySQL(string sqlString) { if (ExpressionTextBox.Text == "") return; Query query = new Query(); query.ReturnGeometry = true; query.OutFields.AddRange(AttributeString.GraphicAttributesEnNameString); query.Where = sqlString; query.OutSpatialReference = map1.SpatialReference; queryTask.ExecuteAsync(query); }
StartQueryBySpatial(ESRI.ArcGIS.Client.Geometry.Geometry geometry):按繪制的空間圖形進行查詢
private void StartQueryBySpatial(ESRI.ArcGIS.Client.Geometry.Geometry geometry) { Query query = new Query(); query.ReturnGeometry = true; query.OutFields.AddRange(AttributeString.GraphicAttributesEnNameString); query.Geometry = geometry; query.OutSpatialReference = map1.SpatialReference; queryTask.ExecuteAsync(query); }
接下來就是點擊不同的按鈕進行查詢了,並對查詢的結果進行處理,例如在地圖上顯示查詢的結果。
注:本文由於查詢的是點要素,所以在查詢的Completed事件完成函數中只對點進行了Symbol顯示操作,如果查詢的結果是面要素還需對面進行處理,讀者可自行添加。
下面是查詢完成對結果處理的代碼:
private void queryTask_ExecuteCompleted(object sender, QueryEventArgs e) { GraphicsLayer graphicsLayer = map1.Layers["QueryResultLayer"] as GraphicsLayer; graphicsLayer.ClearGraphics(); if (e.FeatureSet.Features.Count > 0) { foreach (Graphic resultFeature in e.FeatureSet.Features) { resultFeature.Symbol = new SimpleMarkerSymbol() { Color=new SolidColorBrush(Colors.Red), Size=18, Style=SimpleMarkerSymbol.SimpleMarkerStyle.Circle, }; graphicsLayer.Graphics.Add(resultFeature); } } else { MessageBox.Show("沒有查詢到目標要素!"); } }
空間查詢時在Draw的Competed事件中提交空間查詢請求:
private void myDraw_DrawComplete(object sender, DrawEventArgs e) { StartQueryBySpatial(e.Geometry);
myDraw.IsEnabled = false;
}
其他部分的代碼就是對查詢的輸入進行的一下控制,以及對程序Bug的一些處理(當然依舊還有些bug沒有修復,不過不影響查詢的整體功能,讀者可以自己再修改完善)。
下面給出完整的代碼:Coding-Behind


最后的效果示意圖(結果用紅色的點表示,點擊要素可查看其屬性列表):
1.Where查詢:
a、查詢條件一:Source_ID > 1 and Source_ID < 20 and Source_ID ! = 14
查詢結果:
b、查詢條件二:Source_ID > 1 and Source_Emissions is not null and Source_Emissions < 200
查詢結果:
c.空間查詢
輸入查詢多邊形:
查詢出多邊形內的要素:
源碼及測試數據下載:【下載代碼】
數據使用說明:壓縮文件中的的數據為ArcMap導出的XML文件,使用時,在ArcMap中新建一個地理數據庫,然后右鍵導入,選擇該xml文件,即可生成本例的數據。建議將該數據的服務發布成要素服務,這樣支持Web在線編輯。
(版權所有,轉載請標明出處)