ArcGIS Runtime SDK for .NET (查詢功能實現)


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查詢


免責聲明!

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



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