zoukankan      html  css  js  c++  java
  • Silverlight客户端实现区域像元统计以及地形剖面图的绘制

    开始之前的一段废话:

    放假回家了也就没有写博客了,家里没有网,偶尔也只能用手机上一上,看一看是否有新的评论和回复,是否有和我研究相关的博文和动态。今天是三月一号,学校的校园网帐号解封了,于是便把寒假部分的工作内容总结一下,在此也和大家一起分享我的心得,希望对各位读者能有所帮助。

    本文的例子是我帮一位兄弟做的,算起还是我的学长,只不过不同学校,具体的要求如下:

    http://bbs.esrichina-bj.cn/ESRI/viewthread.php?tid=124221&extra=page%3D1

    于是假期的时候便做了一个该功能的例子,然后还加了一点小功能。后面的文章中将会详细介绍,下面就进入正题吧!

    一、本文实现的功能

    1.1 要素查询功能

    根据要素属性,查询出相应的要素

    1.2 栅格数据的像元统计

    例如输入一个几何图形(点,线,面)可以计算出该图像范围内栅格数据的像元信息,如:像元最大值,最小值,以及平均值等,具体如下图所示:                  

           

     1.3 绘制地形剖面图

     该功能和官网的这个例子差不多:

    http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#SurfaceProfile

    (不知道为什么,我这里查看不了这里例子)

    效果如下图所示:

    二、使用到的数据和知识

    2.1地图数据

            本例的地形高程数据来自于国际科学数据服务平台,下载网址:

    http://datamirror.csdb.cn/index.jsp

            本例的各区县要素数据来自于国家基础地理信息中心,下载网址:

    http://nfgis.nsdi.gov.cn/nfgis/chinese/c_xz.htm

    上面的地图是我自己在ArcMap中制作的一张地图,外加了一点地形阴影效果,这是在ArcMap中的图层列表

     

    各县面要素图层

           

     最后通过以上数据得到了本文使用的底图。在查询部分中,实际上查询的就是各区县的面要素,可通过输入曲线的民称或编号来查询出相对应的县,然后再通过调研像元统计的GP服务工具,即可实现像元统计,得到对应区县范围内像元的最大值,最小值等信息,实际上这里的值也就是对应区县的海拔(准确度由下载的高程数据所决定),最后的地图:

    2.2 使用到如下的知识:

    2.2.1 要素的属性查询

    2.2.2 GP服务的调用

    2.2.3 通过开源的Silverlight图表控件:OxyPlot

    以上前两部分内容都在之前的博文中讲过,所以不是本文的重点。关于OxyPlot图表控件也很简单,这里不会过多的解释说明。官网有很好的帮助文档。

    三、实现过程

    3.1 查询(要素属性查询和空间查询)

    可参考之前的博文:

    http://www.cnblogs.com/potential/archive/2013/01/31/2882244.html

    3.2 根据查询得到的面要素,计算出面要素对应区域内的像元信息。

    3.2.1  发布像元统计的GP服务

    这里主要用到的就是GP服务。下面是本文的GP服务模型:

     

    其中ZoneFiled就是统计字段,InputFeature为输入的要素,ZonalRaster为统计的删格数据

    提醒:在10.1中可以将栅格数据作为输入参数。在10.0中不可以,如果您是10.0版本的,那么这里你只能在建模的时候指定栅格数据,然后去掉设置为模型参数。在10.1中如果你有可数的几个不同栅格数据,那么你可以将其添加到ArcMap中,在发布GP服务的时候,会提示你从列表选择还是自定义栅格数据,这个时候你可以选择从列表选择。然后你可以将ArcMap中的删格数据图层添加到选择列表中,最后在Web端调用的时候,你只需要输入栅格数据列表中对于栅格数据的名称即可,例如本文的列表如下:

     

    这里可以看出只有一个栅格数据选项:hunandata。

    3.2.2   Web端调用GP服务

    调用GP服务的过程之前的博文也有讲到,可参考这里:

    http://www.cnblogs.com/potential/archive/2012/11/03/2752289.html

    下面是本文的调用代码:

     private void AccessGPService(FeatureSet featureset)
            {
                List<GPParameter> gppara = new List<GPParameter>();
                //输入GP服务的参数
                gppara.Add(new GPString("ZoneFiled", "OBJECTID"));
                gppara.Add(new GPFeatureRecordSetLayer("InputFeature", featureset));
                gppara.Add(new GPString("ZonalRaster", "hunandata"));
                _geoprocessor.SubmitJobAsync(gppara);
            }
    
            private void _geoprocessor_JobCompleted(object sender, JobInfoEventArgs e)
            {
                HttpWebRequest.RegisterPrefix("http://", System.Net.Browser.WebRequestCreator.ClientHttp);
                Geoprocessor gp = sender as Geoprocessor;
                //请求GP服务的结果
                gp.GetResultDataAsync(e.JobInfo.JobId, "ResultTable");
            }
    
            private void _geoprocessor_GetResultDataCompleted(object sender, GPParameterEventArgs e)
            {
                MyDataGrid.ItemsSource = null;
                GPRecordSet gpr = e.Parameter as GPRecordSet;
                if (gpr.FeatureSet != null)
                {
                    for (int i = 0; i < gpr.FeatureSet.Features.Count; i++)
                    {
                        for (int j = 2; j < gpr.FeatureSet.Features[i].Attributes.Count; j++)
                        {
                            //这里本文有个Bug,就是当FeatureDataGrid绑定到GraphicsLayer后,
                            //如果修改GrapicsLayer的属性(增加或者删除)会报错,以下代码不能通过,所以这里选择了先修改再绑定
                            List<string> keyList = gpr.FeatureSet.Features[i].Attributes.Keys.ToList<string>();
                            List<object> valueList = gpr.FeatureSet.Features[i].Attributes.Values.ToList();
                            graphicsLayer.Graphics[i].Attributes.Add(keyList[j], valueList[j]);
                        } 
                    }
                    //在此绑定DataGrid,不然会出现异常
                    MyDataGrid.GraphicsLayer = graphicsLayer;
                    MyDataGrid.Visibility = Visibility.Visible;
                    //绘制地形图
                    if (createPlot == true)
                    {
                        CreatePlot();
                        TerrainBorder.Visibility = Visibility.Visible;
                    }
                    featureSet.Features.Clear();
                }
                //等待过程
                BusyRectangle.Visibility = Visibility.Collapsed;
                busyIndicator.IsBusy = false;
            }
    
            private void _geoprocessor_Failed(object sender, TaskFailedEventArgs e)
            {
                MessageBox.Show(e.Error.ToString());
            }

    以上是调用GP服务的代码,这里有个Bug。
    最后的统计结果如下所示:

     

    3.2.3 Web客户端绘制地形图

     这里借助的是开源的图表控件:OxyPlot。感觉绘制图表很强大,而且开源啊。

    绘制地形剖面图的功能大致上的过程如下:

    首先在地图上绘制一条线,然后等分这条线,例如一百份,然后得到这一百个点的像元统计值(最后的值就是海拔值,这里数据的准确度和提供的高程数据经度有关,高程数据经度越高,结果也就越准确),得到一百个点的高程数据之后,就通过OxyPlot绘图了。

    具体代码:

    a.OxyPlot绘图

    声明一个PlotModel,PlotModel代表绘制图表的类型。

    PlotModel plotModel = null;

    在构造函数中初始化:

     var linearAxis1 = new LinearAxis(AxisPosition.Bottom) { IsZoomEnabled=false,Title="距离"};
                plotModel.Axes.Add(linearAxis1);
                var linearAxis2 = new LinearAxis(AxisPosition.Left) { IsZoomEnabled=false,Title="海拔"};
                plotModel.Axes.Add(linearAxis2);
                areaSeries1 = new AreaSeries
                {
                    Fill=OxyColors.DarkOrange,
                    DataFieldX="距离",
                    DataFieldY="最高海拔",
                    DataFieldX2 = "距离",
                    DataFieldY2 = "最低海拔",
                    Color=OxyColors.Red,
                    StrokeThickness=0,
                    MarkerFill=OxyColors.Transparent,
                };

    b.然后绘制一条直线并构造点:

        private void CreatPoint(ESRI.ArcGIS.Client.Geometry.Polyline polyline,int count)
            {
                //默认沿直线构造一百个点
                double xStep = (polyline.Paths[0][1].X - polyline.Paths[0][0].X) / count;
                double yStep = (polyline.Paths[0][1].Y - polyline.Paths[0][0].Y) / count;
                interval = Math.Sqrt(xStep * xStep + yStep * yStep);
                //清空FeatureSet便于之后的GP服务调用
                if (featureSet.Features.Count > 0)
                {
                    featureSet.Features.Clear();
                }
                for (int i = 0; i < count; i++)
                {
                    MapPoint mp = new MapPoint(polyline.Paths[0][0].X + i*xStep, polyline.Paths[0][0].Y + i*yStep);
                    mp.SpatialReference = map1.SpatialReference;
                    Graphic gPoint = new Graphic()
                    {
                        Symbol = new SimpleMarkerSymbol()
                        {
                            Color=new SolidColorBrush(Colors.Blue),
                            Size=8,
                            Style=SimpleMarkerSymbol.SimpleMarkerStyle.Circle
                        },
                        Geometry=mp,
                    };
                    featureSet.Features.Add(gPoint);
                    graphicsLayer.Graphics.Add(gPoint);
                }
            }

    c.调用GP服务统计像元值(代码如上)

    d.根据统计值绘制图表,这里Graphic的MAX属性表示的即为最高海拔,对于点要素MAX和MIN值是一样的。

     private void CreatePlot()
            {
                areaSeries1.Points.Clear();
                areaSeries1.Points2.Clear();
                plotModel.Series.Clear();
    
                for (int i = 0; i < graphicsLayer.Graphics.Count; i++)
                {
                    areaSeries1.Points.Add(new DataPoint(interval * i, Convert.ToDouble(graphicsLayer.Graphics[i].Attributes["MAX"])));
                    areaSeries1.Points2.Add(new DataPoint(interval * i, 0));
                }
                plotModel.Series.Add(areaSeries1);
                areaSeries1.Title = "海拔";
                Myplot.Model = plotModel;
                createPlot = false;
            }

    最后的MainPage.cs代码:

    View Code
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using ESRI.ArcGIS.Client.Symbols;
    using ESRI.ArcGIS.Client.Geometry;
    using ESRI.ArcGIS.Client.Tasks;
    using ESRI.ArcGIS.Client;
    using System.Text.RegularExpressions;
    using OxyPlot.Silverlight;
    using OxyPlot;
    namespace QueryAndStatisticDemo
    {
        public partial class MainPage : UserControl
        {
            //用于查询的Task
            QueryTask queryTask = new QueryTask();
            //声明一个Draw,用于绘制查询的区域,进行空间查询
            Draw myDraw;
            //绘制的Geomotry
            ESRI.ArcGIS.Client.Geometry.Geometry drawGeometry; 
            //查询SQL字符串
            string QueryString;
            //选择查询结果中的Graphic
            Graphic selectedGraphic;
            //地理处理服务
            Geoprocessor _geoprocessor = null;
            //输入要素集
            FeatureSet featureSet = new FeatureSet();
            GraphicsLayer graphicsLayer;
            PlotModel plotModel = null;
            //Interval
            AreaSeries areaSeries1;
            double interval;
            bool createPlot = false;
    
            public MainPage()
            {
                InitializeComponent();
                plotModel = new PlotModel("地形剖面图");
                var linearAxis1 = new LinearAxis(AxisPosition.Bottom) { IsZoomEnabled=false,Title="距离"};
                plotModel.Axes.Add(linearAxis1);
                var linearAxis2 = new LinearAxis(AxisPosition.Left) { IsZoomEnabled=false,Title="海拔"};
                plotModel.Axes.Add(linearAxis2);
                areaSeries1 = new AreaSeries
                {
                    Fill=OxyColors.DarkOrange,
                    DataFieldX="距离",
                    DataFieldY="最高海拔",
                    DataFieldX2 = "距离",
                    DataFieldY2 = "最低海拔",
                    Color=OxyColors.Red,
                    StrokeThickness=0,
                    MarkerFill=OxyColors.Transparent,
                };
                
                graphicsLayer = map1.Layers["QueryResultLayer"] as GraphicsLayer;
    
                queryTask.Url = "http://qzj-pc:6080/arcgis/rest/services/Provinces_Map/HunanMap/MapServer/3";
                queryTask.AutoNormalize = true;
                //很重要,否则出现查询成功和失败交替出现的现象
                queryTask.DisableClientCaching = true;
                queryTask.ExecuteCompleted += new EventHandler<QueryEventArgs>(queryTask_ExecuteCompleted);
                queryTask.Failed += new EventHandler<TaskFailedEventArgs>(queryTask_Failed);
    
                _geoprocessor = new Geoprocessor("http://qzj-pc:6080/arcgis/rest/services/RasterStatisticServer/GPServer/DemStatisticsRaster");
                _geoprocessor.JobCompleted += new EventHandler<JobInfoEventArgs>(_geoprocessor_JobCompleted);
                _geoprocessor.Failed += new EventHandler<TaskFailedEventArgs>(_geoprocessor_Failed);
                _geoprocessor.GetResultDataCompleted += new EventHandler<GPParameterEventArgs>(_geoprocessor_GetResultDataCompleted);
    
                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.LineSymbol = new LineSymbol()
                {
                    Color=new SolidColorBrush(Colors.Red),
                    Width=3
                };
                myDraw.DrawComplete += new EventHandler<DrawEventArgs>(myDraw_DrawComplete);
    
                QueryTypeCombox.ItemsSource = AttributeString.GraphicAttributesEnNameString;
            }
    
            private void myDraw_DrawComplete(object sender, DrawEventArgs e)
            {
                graphicsLayer.Graphics.Clear();
                drawGeometry = e.Geometry;
               
                myDraw.IsEnabled = false;
    
                if (drawGeometry is ESRI.ArcGIS.Client.Geometry.Polyline)
                {
                    CreatPoint((ESRI.ArcGIS.Client.Geometry.Polyline)drawGeometry,100);
                    BusyRectangle.Visibility = Visibility.Visible;
                    busyIndicator.IsBusy = true;
                    AccessGPService(featureSet);
                }
                else
                {
                     StartQueryBySpatial(e.Geometry);
                }
    
            }
    
            private void ExpressionButton_Click(object sender, RoutedEventArgs e)
            {
                string pattern = @"^[0-9]*$";
    
                Button button = sender as Button;
                Match m = Regex.Match(button.Content.ToString(), pattern);
                if (m.Success)
                    ExpressionTextBox.Text = string.Format("{0}{1}", ExpressionTextBox.Text, button.Content);
                else
                    ExpressionTextBox.Text = string.Format("{0} {1} ", ExpressionTextBox.Text, button.Content);
            }
    
            private void ExpressionQueryButton_Click(object sender, RoutedEventArgs e)
            {
                CreatQueryString();
                StartQueryBySQL(QueryString);
            }
    
            private void SpatialQueryButton_Click(object sender, RoutedEventArgs e)
            {
                ExpressionTextBox.Text = "";
                myDraw.DrawMode = DrawMode.Polygon;
                myDraw.IsEnabled = true;
            }
    
            private void FiledsCombox_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                ComboBox comb = sender as ComboBox;
                if (comb.SelectedIndex != -1)
                {
                    int index = comb.SelectedIndex;
                    ExpressionTextBox.Text = string.Format("{0}{1}", ExpressionTextBox.Text, comb.SelectedItem.ToString());
                }
                comb.SelectedIndex = -1;
            }
    
            private void ExpressionTextBox_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
            {
                // 按了回车键就向服务端发送数据
                if (e.Key == Key.Enter)
                {
                    CreatQueryString();
                    StartQueryBySQL(QueryString);
                }
            }
    
            private void QoutButton_Click(object sender, RoutedEventArgs e)
            {
                Button button = sender as Button;
                ExpressionTextBox.Text = string.Format("{0}{1}", ExpressionTextBox.Text, button.Content);
            }
    
            private void NoButton_Click(object sender, RoutedEventArgs e)
            {
                Button button = sender as Button;
                ExpressionTextBox.Text = string.Format("{0} {1}", ExpressionTextBox.Text, button.Content);
            }
    
            private void ClearGraphicsButton_Click(object sender, RoutedEventArgs e)
            {
                graphicsLayer.Graphics.Clear();
            }
    
            private void GraphicsLayer_MouseLeftButtonDown(object sender, GraphicMouseButtonEventArgs e)
            {
                if (selectedGraphic != null)
                {
                    selectedGraphic.UnSelect();
                    selectedGraphic.Symbol = new SimpleFillSymbol()
                    {
                        BorderBrush = new SolidColorBrush(Colors.Red),
                        BorderThickness = 2,
                        Fill = new SolidColorBrush(Colors.Green)
                    };
                }
    
                e.Graphic.Select();
                e.Graphic.Symbol = new SimpleFillSymbol()
                {
                    Fill=new SolidColorBrush(Colors.Red),
                    BorderBrush = new SolidColorBrush(Colors.Yellow),
                    BorderThickness=3
                };
                if (e.Graphic.Selected&&MyDataGrid.GraphicsLayer!=null)
                    MyDataGrid.ScrollIntoView(e.Graphic, null);
                selectedGraphic = e.Graphic;
            }
    
            #region 查询失败几完成事件
            private void queryTask_ExecuteCompleted(object sender, QueryEventArgs e)
            {
    
                graphicsLayer.ClearGraphics();
    
                if (e.FeatureSet.Features.Count > 0)
                {
                    foreach (Graphic resultFeature in e.FeatureSet.Features)
                    {
                        if (drawGeometry != null)
                        {
                            //查询结果落在绘制的多边形之内
                            if (resultFeature.Geometry.Extent.XMax < drawGeometry.Extent.XMax &&
                               resultFeature.Geometry.Extent.XMin > drawGeometry.Extent.XMin &&
                               resultFeature.Geometry.Extent.YMax < drawGeometry.Extent.YMax &&
                               resultFeature.Geometry.Extent.YMin > drawGeometry.Extent.YMin)
                            {
                                resultFeature.Symbol = new SimpleFillSymbol()
                                {
                                    BorderBrush = new SolidColorBrush(Colors.Red),
                                    BorderThickness = 2,
                                    Fill = new SolidColorBrush(Colors.Green)
                                };
                                featureSet.Features.Add(resultFeature);
                                graphicsLayer.Graphics.Add(resultFeature);
                            }
                        }
                        else
                        {
                            resultFeature.Symbol = new SimpleFillSymbol()
                            {
                                BorderBrush = new SolidColorBrush(Colors.Red),
                                BorderThickness = 2,
                                Fill = new SolidColorBrush(Colors.Green)
                            };
                            featureSet.Features.Add(resultFeature);
                            graphicsLayer.Graphics.Add(resultFeature);
                        }
                    }
                    if (graphicsLayer.Graphics.Count < 1)
                        MessageBox.Show("没有查询到目标要素!");
                }
                else
                {
                    MessageBox.Show("没有查询到目标要素!");
                }
                drawGeometry = null;
            }
    
            private void queryTask_Failed(object sender, TaskFailedEventArgs e)
            {
                MessageBox.Show("Query failed: " + e.Error);
            }
    
            #endregion
    
            #region 查询自定义方法
            /// <summary>
            /// 条件查询
            /// </summary>
            /// <param name="sqlString">查询SQL语句</param>
            private void StartQueryBySQL(string sqlString)
            {
                queryTask.CancelAsync();
                if (ExpressionTextBox.Text == "")
                    return;
                Query query = new Query();
                query.ReturnGeometry = true;
                query.OutFields.AddRange(new string[] { "NAME99", "ADCODE99" });
                query.Where = sqlString;
                query.OutSpatialReference = map1.SpatialReference;
                queryTask.ExecuteAsync(query);
            }
            /// <summary>
            /// 空间查询
            /// </summary>
            /// <param name="geometry">几何图形</param>
            private void StartQueryBySpatial(ESRI.ArcGIS.Client.Geometry.Geometry geometry)
            {
                queryTask.CancelAsync();
                Query query = new Query();
                query.ReturnGeometry = true;
                query.OutFields.AddRange(new string[] { "NAME99", "ADCODE99" });
                query.Geometry = geometry;
                query.SpatialRelationship = SpatialRelationship.esriSpatialRelContains;
                query.OutSpatialReference = map1.SpatialReference;
                queryTask.ExecuteAsync(query);
            }
    
            /// <summary>
            /// 构造查询Where条件的SQL语句
            /// </summary>
            private void CreatQueryString()
            {
                if (QueryTypeCombox.SelectedIndex == 0)
                    QueryString =string.Format("NAME99 = '{0}'",ExpressionTextBox.Text);
                else if (QueryTypeCombox.SelectedIndex == 1)
                    QueryString = string.Format("ADCODE99 = '{0}'",ExpressionTextBox.Text);
                else
                    return;
            }
            #endregion
    
            # region 调用GP服务进行栅格像元统计
            private void StatisticButton_Click(object sender, RoutedEventArgs e)
            {
                if (featureSet.Features.Count <= 0)
                    return;
                BusyRectangle.Visibility = Visibility.Visible;
                busyIndicator.IsBusy = true;
                AccessGPService(featureSet);
            }
    
            private void AccessGPService(FeatureSet featureset)
            {
                List<GPParameter> gppara = new List<GPParameter>();
                //输入GP服务的参数
                gppara.Add(new GPString("ZoneFiled", "OBJECTID"));
                gppara.Add(new GPFeatureRecordSetLayer("InputFeature", featureset));
                gppara.Add(new GPString("ZonalRaster", "hunandata"));
                _geoprocessor.SubmitJobAsync(gppara);
            }
    
            private void _geoprocessor_JobCompleted(object sender, JobInfoEventArgs e)
            {
                HttpWebRequest.RegisterPrefix("http://", System.Net.Browser.WebRequestCreator.ClientHttp);
                Geoprocessor gp = sender as Geoprocessor;
                //请求GP服务的结果
                gp.GetResultDataAsync(e.JobInfo.JobId, "ResultTable");
            }
    
            private void _geoprocessor_GetResultDataCompleted(object sender, GPParameterEventArgs e)
            {
                MyDataGrid.ItemsSource = null;
                GPRecordSet gpr = e.Parameter as GPRecordSet;
                if (gpr.FeatureSet != null)
                {
                    for (int i = 0; i < gpr.FeatureSet.Features.Count; i++)
                    {
                        for (int j = 2; j < gpr.FeatureSet.Features[i].Attributes.Count; j++)
                        {
                            //这里本文有个Bug,就是当FeatureDataGrid绑定到GraphicsLayer后,
                            //如果修改GrapicsLayer的属性(增加或者删除)会报错,以下代码不能通过,所以这里选择了先修改再绑定
                            List<string> keyList = gpr.FeatureSet.Features[i].Attributes.Keys.ToList<string>();
                            List<object> valueList = gpr.FeatureSet.Features[i].Attributes.Values.ToList();
                            graphicsLayer.Graphics[i].Attributes.Add(keyList[j], valueList[j]);
                        } 
                    }
                    //在此绑定DataGrid,不然会出现异常
                    MyDataGrid.GraphicsLayer = graphicsLayer;
                    MyDataGrid.Visibility = Visibility.Visible;
                    //绘制地形图
                    if (createPlot == true)
                    {
                        CreatePlot();
                        TerrainBorder.Visibility = Visibility.Visible;
                    }
                    featureSet.Features.Clear();
                }
                //等待过程
                BusyRectangle.Visibility = Visibility.Collapsed;
                busyIndicator.IsBusy = false;
            }
    
            private void _geoprocessor_Failed(object sender, TaskFailedEventArgs e)
            {
                MessageBox.Show(e.Error.ToString());
            }
    
         
            #endregion
    
            private void terrainButton_Click(object sender, RoutedEventArgs e)
            {
                myDraw.DrawMode = DrawMode.Polyline;
                TerrainBorder.Visibility = Visibility.Collapsed;   
                myDraw.IsEnabled = true;
                createPlot = true;
            }
    
            private void CreatPoint(ESRI.ArcGIS.Client.Geometry.Polyline polyline,int count)
            {
                //默认沿直线构造一百个点
                double xStep = (polyline.Paths[0][1].X - polyline.Paths[0][0].X) / count;
                double yStep = (polyline.Paths[0][1].Y - polyline.Paths[0][0].Y) / count;
                interval = Math.Sqrt(xStep * xStep + yStep * yStep);
                //清空FeatureSet便于之后的GP服务调用
                if (featureSet.Features.Count > 0)
                {
                    featureSet.Features.Clear();
                }
                for (int i = 0; i < count; i++)
                {
                    MapPoint mp = new MapPoint(polyline.Paths[0][0].X + i*xStep, polyline.Paths[0][0].Y + i*yStep);
                    mp.SpatialReference = map1.SpatialReference;
                    Graphic gPoint = new Graphic()
                    {
                        Symbol = new SimpleMarkerSymbol()
                        {
                            Color=new SolidColorBrush(Colors.Blue),
                            Size=8,
                            Style=SimpleMarkerSymbol.SimpleMarkerStyle.Circle
                        },
                        Geometry=mp,
                    };
                    featureSet.Features.Add(gPoint);
                    graphicsLayer.Graphics.Add(gPoint);
                }
            }
    
            private void CreatePlot()
            {
                areaSeries1.Points.Clear();
                areaSeries1.Points2.Clear();
                plotModel.Series.Clear();
    
                for (int i = 0; i < graphicsLayer.Graphics.Count; i++)
                {
                    areaSeries1.Points.Add(new DataPoint(interval * i, Convert.ToDouble(graphicsLayer.Graphics[i].Attributes["MAX"])));
                    areaSeries1.Points2.Add(new DataPoint(interval * i, 0));
                }
                plotModel.Series.Add(areaSeries1);
                areaSeries1.Title = "海拔";
                Myplot.Model = plotModel;
                createPlot = false;
            }
    
            private void Button_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
            {
                // TODO: Add event handler implementation here.
                BusyButton.Content = "取消";
            }
    
            private void Button_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
            {
                // TODO: Add event handler implementation here.
                BusyButton.Content = "正在计算...";
            }
    
            private void BusyButton_Click(object sender, System.Windows.RoutedEventArgs e)
            {
                // TODO: Add event handler implementation here.
                BusyRectangle.Visibility = Visibility.Collapsed;
                busyIndicator.IsBusy = false;
            }
        }
    }

    最后的MainPage.xaml代码:

    View Code
    <UserControl
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:oxy="clr-namespace:OxyPlot.Silverlight;assembly=OxyPlot.Silverlight" 
        xmlns:esri="http://schemas.esri.com/arcgis/client/2009" xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit" x:Class="QueryAndStatisticDemo.MainPage"
        mc:Ignorable="d"
        d:DesignHeight="760" d:DesignWidth="960" 
        >
    
        <Grid x:Name="LayoutRoot">
            <Grid.Background>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="#FF65C0A5" Offset="0"/>
                    <GradientStop Color="#FF1E1E1F" Offset="1"/>
                    <GradientStop Color="#FF22555C" Offset="0.428"/>
                    <GradientStop Color="#FF596EA1" Offset="0.681"/>
                </LinearGradientBrush>
            </Grid.Background>
            <Grid.RowDefinitions>
                <RowDefinition Height="120"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <!--Map-->
            <esri:Map x:Name="map1" WrapAround="True" VerticalContentAlignment="Stretch" Grid.RowSpan="2" Margin="0">
                <esri:Map.Layers>
                    <esri:LayerCollection>
                        <esri:ArcGISDynamicMapServiceLayer Url="http://qzj-pc:6080/arcgis/rest/services/Provinces_Map/HunanMap/MapServer" />
                        <esri:GraphicsLayer ID="QueryResultLayer" Opacity="0.8" MouseLeftButtonDown="GraphicsLayer_MouseLeftButtonDown"/>
                    </esri:LayerCollection>
                </esri:Map.Layers>
            </esri:Map>
          
            <!--QueryBorder-->
            <Border BorderBrush="Black" BorderThickness="1" Margin="8" CornerRadius="5" Background="#7F94BCE0">
                <Grid>
                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                        <StackPanel VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10,0,10,0">
                            <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
                                <Button x:Name="MorethanButton1" Content="1" Height="23" Width="48" Click="ExpressionButton_Click" />
                                <Button x:Name="LessthanButton2" Content="2" HorizontalAlignment="Left" Height="23" Width="48" Click="ExpressionButton_Click" />
                                <Button x:Name="EqualButton1" Content="3" Height="23" Width="43" Click="ExpressionButton_Click" />
                            </StackPanel>
                            <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
                                <Button x:Name="MoreOrEButton1" Content="4" HorizontalAlignment="Left" Height="23" Width="48" Click="ExpressionButton_Click" />
                                <Button x:Name="LessOrEqualButton1" Content="5" HorizontalAlignment="Left" Height="23" Width="48" Click="ExpressionButton_Click" />
                                <Button x:Name="LessAndMoreButton1" Content="6" Height="23" Width="43" HorizontalAlignment="Left" Click="ExpressionButton_Click" />
                            </StackPanel>
                            <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
                                <Button x:Name="LikeButton1" Content="7" HorizontalAlignment="Left" Height="23" Width="48" Click="ExpressionButton_Click" />
                                <Button x:Name="AndButton1" Content="8" HorizontalAlignment="Left" Height="23" Width="48" Click="ExpressionButton_Click" />
                                <Button x:Name="OrButton1" Content="9" Height="23" Width="43" Click="ExpressionButton_Click" />
                            </StackPanel>
                            <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
                                <Button x:Name="NotButton1" Content="0" HorizontalAlignment="Left" Height="23" Width="48" Click="ExpressionButton_Click" />
                                <Button x:Name="QoutButton" Content="'" HorizontalAlignment="Left" Height="23" Width="48" ToolTipService.ToolTip="单引号" Click="QoutButton_Click" />
                                <Button x:Name="NoButton" Content="!" Height="23" Width="43" ToolTipService.ToolTip="非运算" Click="NoButton_Click" />
                            </StackPanel>
                        </StackPanel>
                        <StackPanel VerticalAlignment="Top" HorizontalAlignment="Center" Margin="0">
                            <StackPanel Orientation="Horizontal" Margin="0,10,0,0">
                            <TextBlock  TextWrapping="Wrap" Text="查询条件:" Height="18" Margin="20,0,0,0" FontSize="14" FontWeight="Bold" Foreground="Red"/>
                                <ComboBox x:Name="QueryTypeCombox" Height="23" Width="130" SelectedIndex="0" Margin="0,0,10,0"/>
                                <TextBox x:Name="ExpressionTextBox" TextWrapping="Wrap" Height="27" Margin="0,5,0,0" Width="150" KeyDown="ExpressionTextBox_KeyDown"/>
                            </StackPanel>
                                <StackPanel Orientation="Horizontal" Margin="0,10,0,0">
                                <Button x:Name="ExpressionQueryButton" Content="条件查询" Height="30" Width="70" Margin="20,0,0,0" Click="ExpressionQueryButton_Click"/>
                                <Button x:Name="SpatialQueryButton" Content="空间查询" Height="30" Width="70" Click="SpatialQueryButton_Click" Margin="10,0,0,0" />
                                <Button Content="绘制地形图" Height="30" x:Name="terrainButton" Width="75" Margin="20,0,0,0" Click="terrainButton_Click"/>
                            </StackPanel>
                        </StackPanel>
                        <StackPanel VerticalAlignment="Center" HorizontalAlignment="Left" Margin="20,0,20,0">
                            <Button Width="135" Height="23" x:Name="StatisticButton" Content="地形统计" Margin="0,5,0,0" Click="StatisticButton_Click" />
                            <Button x:Name="ClearExpressionButton" Content="清空查询语句" Height="23" Width="135" Click="SpatialQueryButton_Click"  Margin="0,10,0,0" />
                            <Button Width="135" Height="23" x:Name="ClearGraphicsButton" Content="清空图层" Margin="0,10,0,0" Click="ClearGraphicsButton_Click" />
                          </StackPanel>
                    </StackPanel>
                </Grid>
            </Border>
       
            <!--StatisticResultForm-->
            <esri:FeatureDataGrid x:Name="MyDataGrid" HorizontalAlignment="Right" Margin="0,0,20,20" VerticalAlignment="Bottom" 
                                  Map="{Binding ElementName=map1}"
                                  Width="400" Height="200"
                                  Grid.Column="0" Grid.Row="1"  SelectionMode="Single" VerticalGridLinesBrush="#FF31D8D8" HorizontalGridLinesBrush="#FF31B1B1" RowBackground="#AA3C8A99" Visibility="Collapsed" >
                <esri:FeatureDataGrid.Effect>
                    <DropShadowEffect/>
                </esri:FeatureDataGrid.Effect>
                <esri:FeatureDataGrid.Background>
                    <LinearGradientBrush EndPoint="0.894,0.85" StartPoint="-0.076,-0.033">
                        <GradientStop Color="#FF56585E"/>
                        <GradientStop Color="#FF1B8D85" Offset="1"/>
                    </LinearGradientBrush>
                </esri:FeatureDataGrid.Background>
            </esri:FeatureDataGrid>
    
            <Border BorderThickness="1" Grid.Row="1" Height="260" HorizontalAlignment="Left" Margin="20" x:Name="TerrainBorder" VerticalAlignment="Bottom" Width="400" CornerRadius="10" Visibility="Collapsed">
                <Border.Effect>
                    <DropShadowEffect/>
                </Border.Effect>
                <oxy:Plot x:Name="Myplot" Foreground="#FFE9E5E5" >
                    <oxy:Plot.Effect>
                        <DropShadowEffect/>
                    </oxy:Plot.Effect>
                    <oxy:Plot.Background>
                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                            <GradientStop Color="#FF0F4549" Offset="0"/>
                            <GradientStop Color="#B266AABA" Offset="1"/>
                            <GradientStop Color="#DA8F9EA1" Offset="0.471"/>
                        </LinearGradientBrush>
                    </oxy:Plot.Background>
                </oxy:Plot>
            </Border>
            <Rectangle x:Name="BusyRectangle" Fill="#FF454552" Stroke="Black" Grid.RowSpan="2" Opacity="0.5" Visibility="Collapsed"/>
            <toolkit:BusyIndicator x:Name="busyIndicator" Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center" IsBusy="False">
                <toolkit:BusyIndicator.BusyContent>
                    <Grid>
                        <Button x:Name="BusyButton" Height="23" Width="199" Content="正在计算..." MouseEnter="Button_MouseEnter" MouseLeave="Button_MouseLeave" Padding="3" Click="BusyButton_Click"/>
                    </Grid>
                </toolkit:BusyIndicator.BusyContent>
            </toolkit:BusyIndicator>
        </Grid>
    </UserControl>

    最终的效果:

    按县区名称查询双峰县,结果如下图所示:

    正在统计双峰县的像元信息

    统计结果如下图所示:

     

    绘制一条直线

    通过直线得到构造点,并进行像元统计

     

    最后的统计结果,及地下剖面图,根据直线经过的地方来看,地形图是正确的。

     

    在图上可以查看剖面图的数据:

    空间查询,并进行统计

    总结:以上的过程大致上说了一下Web端区域像元统计的过程,其中涉及到了要素查询,GP服务,Web端栅格数据作为输入数据的处理问题,OxyPlot图表控件的使用,FeatureDataGrid的数据绑定等,有些内容进行了详细的说明,有些由于时间限制就没有进行细致的说明,在此还望谅解。有什么问题可以留言反映,我一定都会逐一回复。当然程序中还有很多Bug,也没有处理,程序的结构也不是很好,代码质量也不高,希望高手勿喷,欢迎您提出宝贵的意见和分享您的解决方法。

    还有需要提醒一点的是本文使用的服务都是我自己发布的服务,所以您需要自己发布程序中用到的服务。

     【源码下载

  • 相关阅读:
    xpath取其中几个使用position
    pycharm2018.3.5 下载激活(windows平台)
    switch host 切换本地host
    leveldb 学习记录(四)Log文件
    bittorrent 学习(一) 种子文件分析与bitmap位图
    分布式协议学习笔记(三) Raft 选举自编写代码练习
    谷歌开源的一个BTREE实现 Go语言
    分布式协议学习笔记(二) 日志复制
    分布式协议学习笔记(一) Raft 选举
    利用redis制作消息队列
  • 原文地址:https://www.cnblogs.com/potential/p/2938361.html
Copyright © 2011-2022 走看看