1、界面設計
<MenuItem Header="查詢" Height="30" Width="100" Background="CadetBlue" BorderBrush="Aqua" BorderThickness="1">
<MenuItem Header="簡單查詢" Height="30" BorderBrush="Khaki" BorderThickness="2" Click="easyQuery"/>
<MenuItem Header="點擊查詢" Height="30" BorderBrush="Khaki" BorderThickness="2" Click="MenuSelectFeat_Click"/>
<MenuItem Header="Identity查詢" Height="30" BorderBrush="Khaki" BorderThickness="2" Click="MenuIdentify_Click"/>
</MenuItem>
2、C#代碼實現
簡單查詢
private async Task QueryStateFeature3(FeatureLayer _featureLayer, string sQueryFieldName, string stateName)
{
try
{ // 定義 一個查詢參數對象
QueryParameters pQueryP = new QueryParameters();
string sformat = stateName.Trim().ToUpper(); // 去掉地名兩邊的空格,並轉為大寫
// 設置查詢條件
pQueryP.WhereClause = "upper(" + sQueryFieldName + ") LIKE '%" + sformat + "%'"; // where語句,將字段名轉成大寫
// 依據查詢參數,進行要素選擇操作
//Esri.ArcGISRuntime.Mapping.SelectionMode.Add 將要選擇的要素附加到當前選定要素列表中。
//Esri.ArcGISRuntime.Mapping.SelectionMode.New 將當前選定要素列表替換為要選定的要素。
//Esri.ArcGISRuntime.Mapping.SelectionMode.Subtract 從當前選定要素列表中刪除要素。
//_featureLayer.SelectFeaturesAsync(查詢表達式,查詢模式)
await _featureLayer.SelectFeaturesAsync(pQueryP, Esri.ArcGISRuntime.Mapping.SelectionMode.New); // 等待其查詢完畢
//提取已選擇的要素
//_featureLayer.GetSelectedFeaturesAsync() 表示異步獲取選定功能操作的任務對象。任務結果的值是FeatureQueryResult對象;僅顯示選定的功能。
FeatureQueryResult pQueryResult = await _featureLayer.GetSelectedFeaturesAsync();
// 存到列表中
List<Feature> pListFeatures = pQueryResult.ToList();
//使用空間引用和空幾何體初始化EnveloperBuilder類的新實例。
EnvelopeBuilder pEnvBuilder = new EnvelopeBuilder(MyMapView.Map.SpatialReference);
for (int i = 0; i < pListFeatures.Count; i++)
{
//查找此生成器形狀和給定形狀的並集。此生成器的形狀將根據結果進行更新。
pEnvBuilder.UnionOf(pListFeatures[i].Geometry.Extent);
}
//縮放到提供的幾何體。即使幾何體不規則,下面的函數會自動找出可以包含進所有外形的矩形,並向外擴展50像素。
await MyMapView.SetViewpointGeometryAsync(pEnvBuilder.ToGeometry(), 50);
//顯示選擇要素的屬性。
}
catch (Exception ex)
{
MessageBox.Show("An error occurred.\n" + ex, "Sample error");
}
}
// 簡單查詢
private async void easyQuery(object sender, RoutedEventArgs e)
{
string sQueryFieldName = "Name"; //圖層字段名
string stateName = "New York"; //圖層字段名里的某個屬性
//獲取圖層,該圖層為實例1中加載FeatureLayer數據,默認放在第一層(圖層名為 “States” )
// Map.OperationalLayers 獲取或設置映射中操作層的集合。
FeatureLayer _featureLayer = MyMapView.Map.OperationalLayers[0] as FeatureLayer;
if (_featureLayer != null)
await QueryStateFeature3(_featureLayer, sQueryFieldName, stateName); // 調用方法
}
點擊查詢 & identity查詢
enum CURRENTOPERATION
{
NullOpe = -1,
SelectQuery = 0,
IdentifyQuery,
PanMap,
};
namespace classTest
{
public partial class MainWindow : Window
{
......
CURRENTOPERATION m_CurOper;
public MainWindow()
{
......
m_CurOper = CURRENTOPERATION.NullOpe;
......
}
......
}
......
}
除了下面代碼外,還需要添加上面圖中的代碼
private async void FunClickQuery(MapPoint pPoint, FeatureLayer _featureLayer)
{
double tol = 3;
// MyMapView.UnitsPerPixel 以貼圖單位獲取每個設備獨立像素的當前大小。
//mapTol 這個容差,就是你鼠標點擊的位置,以它為中心,以容差為半徑,構建一個幾何圖形
//你可以試試把容差改大點,然后在點擊查詢的時候,靠近邊界來點,它肯定會選擇到以你點的位置為軸心,容差為半徑的范圍內的圖形,並高亮起來
double mapTol = tol * MyMapView.UnitsPerPixel; // 設置選擇容差
MapPoint pNormalPoint = pPoint;
//點坐標處理,如果地圖是無邊界漫游的,則幾何體需要正則化
//MyMapView.IsWrapAroundEnabled 指示環繞功能當前是否處於活動狀態。要激活環繞,必須將WrapAroundMode屬性設置為true,並且MapView控件的SpatialReference必須是支持環繞的SpatialReference。
if (MyMapView.IsWrapAroundEnabled)
{
//GeometryEngine.NormalizeCentralMeridian(pPoint) 將幾何體折疊到360度范圍內。在地圖上啟用環繞時,這可能是必需的。如果幾何體是封套,則將返回多邊形,除非封套為空,否則將返回空封套。
pNormalPoint = (MapPoint)GeometryEngine.NormalizeCentralMeridian(pPoint);
}
//依據點坐標及容差,構建搜索矩形
Envelope selEnv = new Envelope(pNormalPoint.X - mapTol, pNormalPoint.Y - mapTol, pNormalPoint.X +
mapTol, pNormalPoint.Y + mapTol, MyMapView.SpatialReference);
//准備查詢條件
QueryParameters pQueryPara = new QueryParameters();
pQueryPara.Geometry = selEnv; // 獲取或設置用於篩選結果的幾何體。
pQueryPara.SpatialRelationship = SpatialRelationship.Intersects; // 獲取或設置幾何體參數和要素之間的空間關系類型。
//此方法是確定兩個幾何圖形之間空間關系的幾種方法之一。如果兩個輸入幾何體之間存在空間關系,則返回true。如果兩個輸入幾何圖形之間不存在空間關系,則返回false。
await _featureLayer.SelectFeaturesAsync(pQueryPara, Esri.ArcGISRuntime.Mapping.SelectionMode.New);
//提取已選擇的要素,居中顯示
//_featureLayer.GetSelectedFeaturesAsync() 表示異步獲取選定功能操作的任務對象。任務結果的值是FeatureQueryResult對象;僅顯示選定的功能。
FeatureQueryResult pQueryResult = await _featureLayer.GetSelectedFeaturesAsync();
// 存到列表中
List<Feature> pListFeatures = pQueryResult.ToList();
if (pListFeatures.Count <= 0)
return;
//使用空間引用和空幾何體初始化EnveloperBuilder類的新實例。
EnvelopeBuilder pEnvBuilder = new EnvelopeBuilder(_featureLayer.SpatialReference);
for (int i = 0; i < pListFeatures.Count; i++)
{
//查找此生成器形狀和給定形狀的並集。此生成器的形狀將根據結果進行更新。
pEnvBuilder.UnionOf(pListFeatures[i].Geometry.Extent);
}
//縮放到提供的幾何體。即使幾何體不規則,下面的函數會自動找出可以包含進所有外形的矩形,並向外擴展50像素。
await MyMapView.SetViewpointGeometryAsync(pEnvBuilder.ToGeometry(), 50);
//顯示選擇要素的屬性。
Feature pFeature; string sInfo = "";
//IReadOnlyList 執行地理編碼操作以查找給定地址和一組搜索參數的候選位置
IReadOnlyList<Field> pFields = pQueryResult.Fields; // 獲取圖集的字段。
// 話說點擊查詢和id查詢不應該是唯一的嗎,為啥要循環呢
for (int i = 0; i < pListFeatures.Count; i++)
{
pFeature = pListFeatures[i];
// 提取屬性方法一, 部分字段值的屬性無法獲取,容易報錯 ===== www重點
//sInfo += "選中的第" + i.ToString() + "個要素的屬性\n\r";
//for (int j = 0; j < pFields.Count; j++)
//{
// sInfo += pFields[j].Name + ": ";
// //????下面這一行報錯,可以取出ObjectID ,Name的值。字段名為ID, STATE_NAME等,字段值取出報錯。
// object temp = pFeature.GetAttributeValue(pFields[j].Name);
// sInfo += pFeature.GetAttributeValue(pFields[j]).ToString() + "\n\r";
//}
// 提取屬性方法二, 部分字段值的屬性無法獲取,pFeature.Attributes; 直接將可提取的字段屬性拿出來,不會報錯。
IDictionary<string, object> FeatureAttri = pFeature.Attributes; // 就是字段名,字段值 二者形成一個字典對象
string str; object obj;
sInfo += "選中的第" + i.ToString() + "個要素的屬性\n\r";
for (int j = 0; j < FeatureAttri.Count; j++)
{
str = FeatureAttri.Keys.ElementAt(j);
obj = FeatureAttri.Values.ElementAt(j);
sInfo += str + ":" + obj.ToString() + "\r\n";
}
}
MessageBox.Show(sInfo);
}
// FunIdentifyQuery 為 Idenify 查詢函數
private async void FunIdentifyQuery(System.Windows.Point pPoint, FeatureLayer pFLayer)
{
// 執行Identiy.
//IdentifyLayerResult 獲取標識的IdentifyLayerResult的列表。
//GeoView.IdentifyLayerAsync Method(Layer, Point, Double, Boolean) 在指定圖層上啟動標識操作,該操作將僅返回單個可見的最上面的地理元素。
IdentifyLayerResult myIdentifyResult = await MyMapView.IdentifyLayerAsync(pFLayer, pPoint, 20, false);
// 如果結果為空,退出
if (!myIdentifyResult.GeoElements.Any())
{
return;
}
//修改以下代碼,循環遍歷所有選中的要素
// 得到查詢結果中的第一個圖層
Feature identifiedFeature = (Feature)myIdentifyResult.GeoElements[0];
//獲取要素的屬性
IDictionary<string, object> FeatureAttri = identifiedFeature.Attributes;
string str;
string tempStr = "";
object obj;
for (int i = 0; i < FeatureAttri.Count; i++)
{
str = FeatureAttri.Keys.ElementAt(i);
obj = FeatureAttri.Values.ElementAt(i);
tempStr += str + ":" + obj.ToString() + "\r\n";
}
MessageBox.Show(tempStr);
}
private void MenuSelectFeat_Click(object sender, RoutedEventArgs e)
{
m_CurOper = CURRENTOPERATION.SelectQuery; // 點擊查詢時,更改當前變量值為 0
}
private void MenuIdentify_Click(object sender, RoutedEventArgs e)
{
m_CurOper = CURRENTOPERATION.IdentifyQuery; // id查詢時,更改當前變量值為 1
}
private void MyMapView_GeoViewTapped(object sender, Esri.ArcGISRuntime.UI.Controls.GeoViewInputEventArgs e)
{
//點擊查詢
if (m_CurOper == CURRENTOPERATION.SelectQuery)
{
if (MyMapView.Map.OperationalLayers.Count > 0)
{
FeatureLayer _featureLayer = MyMapView.Map.OperationalLayers[0] as FeatureLayer;
if (_featureLayer != null)
{
FunClickQuery(e.Location, _featureLayer);
}
}
}
//Identify查詢
else if (m_CurOper == CURRENTOPERATION.IdentifyQuery)
{
if (MyMapView.Map.OperationalLayers.Count > 0)
{
FeatureLayer _featureLayer = MyMapView.Map.OperationalLayers[0] as FeatureLayer;
if (_featureLayer != null)
{
FunIdentifyQuery(e.Position, _featureLayer);
}
}
}
//考慮編寫代碼,實現地圖漫游功能
else if (m_CurOper == CURRENTOPERATION.PanMap)
{
}
}
3、結果
簡單查詢
點擊查詢
identity查詢