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

posted @   槑孒  阅读(561)  评论(1编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
点击右上角即可分享
微信分享提示