zoukankan      html  css  js  c++  java
  • 使用ArcGIS API for Silverlight 进行复合多条件空间查询

              这两天帮网上认识的一个兄弟做了一个查询的示例,多多少少总结一下,在此和大家分享。

    为什么说是复合多条件呢?因为进行空间查询有时候我们查询的条件会很复杂,比如要求某一要素的某一属性大于多少,且小于多少,且又不等于多少等等。而在官网给出的例子中并没有关于复合查询的说明。不过查看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

    View Code

    说明:

     在前台页面还增加了要素的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

    MainPage.cs
    AttributeString.cs

    最后的效果示意图(结果用红色的点表示,点击要素可查看其属性列表):

    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在线编辑。

    (版权所有,转载请标明出处)

  • 相关阅读:
    DataGridView 设置行不可见时,与货币管理器的位置关联的行不能设置为不可见
    DataGridView 冻结列后出现 无法添加该列,原因是它被冻结并被置于未冻结的列之后
    sql 2000 查询中增加序号列,自动增加列
    SQL 语法大全
    清除vs2003vs2008起始页最近打开项目
    ALTER TABLE 修改表时 因为有一个或多个对象访问此列
    UNIX上C++程序设计守则(信号和线程)(上)
    Thread Cancel 指南
    [C++再学习系列] 深入new/delete:New的3种形态
    设计模式学习(六):重构与模式,推荐书籍(完)
  • 原文地址:https://www.cnblogs.com/potential/p/2882244.html
Copyright © 2011-2022 走看看