博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ArcGIS网络分析之Silverlight客户端最近设施点分析(四)
阅读量:5137 次
发布时间:2019-06-13

本文共 8146 字,大约阅读时间需要 27 分钟。

    在上一篇中说了如何实现最近路径分析,本篇将讨论如何实现最近设施点分析。

最近设施点分析实际上和路径分析有些相识,实现的过程基本一致,不同的是参数的设置,选用的分析图层为最近设施点网络分析图层,一般形式为:

http://<服务器名或ip地址>/ArcGIS/rest/services/<地图服务名称>/NAServer/<最近设施点分析图层名称>

在ArcGIS Api for Silverlight中,最近设施点分析的参数名称为:RouteClosestFacilityParameters,同样它也继承自BaseRouteParameters。其主要的参数(属性)有:

    属性名称            
Incidents 表示事件点
Facilities 表示设施点
Barriers 表示障碍点,还有线障碍:PolylineBarriers,面障碍:PolygonBarriers
DefaultCutoff 表示默认终断值,即不会搜索超出该值的设施点(从事件点到设施点,反之同理)
ReturnDirections 表示是否返回方向指南
DirectionsLanguage 表示返回方向指南使用的描述语言(默认与网络分析图层一致,NAServer中只有英语,其他语言需要自己安装)
DirectionsLengthUnits 表示计算方向时使用的长度单位。默认与路径网络图层的设置一致。可用的值包括esriFeet,esriKilometers, esriMeters,esriMile,esriNauticalMiles和esriYards
ReturnRoutes 表示是否返回设施点与事件点的路径
ReturnFacilities 表示是否返回设施点
ReturnIncidents 表示是否返回事件点
TravelDirection 表示路径的方向(从设施点到事件点还是事件点到设施点)
UseHierarchy 表示是否启用等级属性
FacilityReturnType 表示设施返回类型,默认为FacilityReturnType.ServerFacilityReturnAll
DefaultTargetFacilityCount 表示默认搜索的设施点个数

 

以上是最近设施点参数中一般用到的属性说明。

下面我们来看一下实现的具体过程。

1.首先我们需要一个最近设施点的网络分析图层,并实例化一个RouteTask。

例如本文发布的最近设施点的网络分析图层地址为:

实例化RouteTask

RouteTask closestFacilityTask = new RouteTask("http://qzj-pc/ArcGIS/rest/services/NetworkAnaysisMap/NAServer/ClosestFacility");//最近设施点Task

这里在之前的博文中已经说了网络分析图层的建立和发布。在此不再讨论。

2.注册RouteTask的完成和失败事件

注册事件:

closestFacilityTask.SolveClosestFacilityCompleted += new EventHandler
(closestFacilityTask_SolveClosestFacilityCompleted);closestFacilityTask.Failed += new EventHandler
(Task_Failed);

事件完成响应函数:

private void closestFacilityTask_SolveClosestFacilityCompleted(object sender, RouteEventArgs e)        {        //获取结果的代码         }private void Task_Failed(object sender, TaskFailedEventArgs e)        {            MessageBox.Show("求解失败" + e.Error.ToString());        }

3.设置最近设施点分析的参数,即RouteClosestFacilityParameters,例如:

RouteClosestFacilityParameters closestFacilityParameter = new RouteClosestFacilityParameters()            {                //设置事件点                Incidents = stopsGraphicsLayer.Graphics,                //设置设置点                Facilities = gplayer.Graphics,                //设置障碍点                Barriers = barriesGraphicsLayer.Graphics,                ReturnDirections = true,                DirectionsLanguage = new System.Globalization.CultureInfo("en-US"),                ReturnRoutes = true,                ReturnFacilities = true,                ReturnBarriers = false,                ReturnIncidents = true,                ReturnPolygonBarriers = false,                ReturnPolylineBarriers = false,                DefaultCutoff = 100000,                FacilityReturnType = FacilityReturnType.ServerFacilityReturnAll,                DefaultTargetFacilityCount = Convert.ToInt32(ClosestFaciclityNumTextBox.Text),                TravelDirection = FacilityTravelDirection.TravelDirectionToFacility,                OutSpatialReference = MyMap.SpatialReference,            };

以上过程省略了关于添加障碍点和事件点的过程,其过程和最短路径分析的过程完全一致,所以在此不再多做解释,具体过程可以参考前一篇的博文

4.进行最近设施点分析

if (closestFacilityTask.IsBusy)                closestFacilityTask.CancelAsync();            closestFacilityTask.SolveClosestFacilityAsync(closestFacilityParameter);

5.获取分析结果,以及处理分析失败的情况

最近设施点查询返回的结果和最短路径是一样的,参数都是RouteEventArgs。所以这里我们取得RouteEventArgs中的RouteResults集合即可。

但是对结果的处理方式和最短路径又有一点点小差别。因为最短路径返回的结果只有一条路径,而最近设施点的分析结果则根据查询的设施点不同而不同,例如我们想查询最近的3个设施点,如果查询成功,并且找到最近的三个设施点,那么返回的路径就有3条。

所以这里我们需要对设施点查询返回的结果进行循环。然后剩下的工作就和最短路径一样了。

这里我们选择用TreeView控件来显示不同的路径,最后生成的界面如下:

例如查询附近4个最近的警察局,获得四条路线,并可以展看查看每一天的详情:

同时当选中一条路径时(位置1-第二警局),高亮显示。

示例代码如下:

private void closestFacilityTask_SolveClosestFacilityCompleted(object sender, RouteEventArgs e)        {            //清空显示方向的面板            DirectionStackPanel.Children.Clear();            //情况路线图层(即上一次查询的结果)            RoutegraphicsLayer.Graphics.Clear();            //定义一个TreeView控件,将用于显示路径            TreeView RouteTree = new TreeView();            //注册TreeView事件,当选择不同的节点时,高亮显示相应的路径            RouteTree.SelectedItemChanged += new RoutedPropertyChangedEventHandler(RouteTree_SelectedItemChanged);            //遍历返回的结果(路线)            foreach (RouteResult SolvedRoute in e.RouteResults)            {                RouteResult routeResult = SolvedRoute;                //定义路线样式                routeResult.Route.Symbol = LayoutRoot.Resources["MyRouteLineSymbol"] as SimpleLineSymbol;                //将路线添加到图层中                RoutegraphicsLayer.Graphics.Add(routeResult.Route);                //添加一个Item,即表示当前的路线。将路线以树视图的形式展示出来                TreeViewItem RouteItem = new TreeViewItem();                //树视图一级标题格式:
<路线id>
.
<路线名称>
RouteItem.Header = string.Format("{0}: {1}", SolvedRoute.Directions.RouteID, SolvedRoute.Directions.RouteName); //将TreeViewItem的Tag设置为相应路线的ID,以便之后高亮显示其对应路线。 RouteItem.Tag = SolvedRoute.Directions.RouteID; int i = 1; foreach (Graphic g in routeResult.Directions) { StringBuilder direction = new StringBuilder(); direction.AppendFormat("{0}. {1}", i, g.Attributes["text"]); if (i > 1 && i < routeResult.Directions.Features.Count) { decimal Distance = (decimal)g.Attributes["length"]; direction.AppendFormat(" {0}米", Distance.ToString("#0.000")); decimal NeedTime = (decimal)g.Attributes["time"]; direction.AppendFormat(", {0}分钟", NeedTime.ToString("#0.00")); } RouteItem.Items.Add(new TextBlock() { Text = direction.ToString(), Margin = new Thickness(4) }); i++; } //添加总时间和路程的属性 RouteItem.Items.Add(new TextBlock() { Text = string.Format(" 总路程为:{0}千米\n\n 总时间为:{1}分钟", (SolvedRoute.Directions.TotalLength).ToString("#0.000"), SolvedRoute.Directions.TotalDriveTime.ToString("#0.00")) }); //遍历一条路线结束,将该路线的信息添加到TreeView中,TreeView获得一个节点。 RouteTree.Items.Add(RouteItem); } //遍历路线结束,将路线结果添加到显示方向的面板中。 DirectionStackPanel.Children.Add(RouteTree); }

 高亮显示当前选中的路线,并取消高亮上一次选择的路线,示例代码如下:

//记录上一次点击的是哪一个节点       int OldIndex = 0;       private void RouteTree_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs e)        {           //必须点击节点才有效,节点下的TextBlock虽然也能触发Changed事件,但是无效            if (e.NewValue.ToString() == typeof(TextBlock).ToString())            {                return;            }            //如果旧值不为空,即不是第一次点击,那么上一次点击就有可能是节点还有可能是节点下的TextBlock。            //因为当点击不同的节点时,我们需要将上一次高亮显示的路线不高亮,而高亮显示本次选中的路线            //所以在此需要处理            if (e.OldValue != null)            {                //如果上一次点击的是TreeViewItem则直接将其还原成不高亮显示                if (e.OldValue.ToString() == typeof(TreeViewItem).ToString())                {                       TreeViewItem treeViewItem = (TreeViewItem)e.OldValue;                    OldIndex = Convert.ToInt32(treeViewItem.Tag);                    //在Tag中1表示的是第一条路线,其对应Graphics的索引值为0,一次类推减1.                    RoutegraphicsLayer.Graphics[OldIndex - 1].Symbol = LayoutRoot.Resources["MyRouteLineSymbol"] as SimpleLineSymbol;                }//如果上一次点击的不是TreeView,则需要通过记录上一次点击的索引:Oldindex来确定上一次点击的是那一个TreeView,并将其还原成不高亮                else                {                    RoutegraphicsLayer.Graphics[OldIndex].Symbol = LayoutRoot.Resources["MyRouteLineSymbol"] as SimpleLineSymbol;                }            }            //获得当前点击节点的索引            int currentIndex = Convert.ToInt32(((TreeViewItem)((TreeView)sender).SelectedItem).Tag);           //高亮显示当前选择的路线            RoutegraphicsLayer.Graphics[currentIndex - 1].Symbol = LayoutRoot.Resources["RouteRenderer"] as SimpleLineSymbol;           //将本次点击的所以赋给OldIndex.            OldIndex = currentIndex - 1;        }

这样所有的工作基本就已经完成了。下面是整体效果图:

注:以上内容参考了ERSI官网例子,以及ESRI中国编写的ArcGIS Api For Silverlight指导教程。

下一篇将讲解服务区分析的实现过程,欢迎关注!

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

转载于:https://www.cnblogs.com/potential/archive/2012/11/17/2775141.html

你可能感兴趣的文章
CentOS 如何删除/delete/remove 老的 kernel
查看>>
架构设计基础-软件架构设计学习第二天(非原创)
查看>>
子系统迁移存储过程
查看>>
Package should contain a content type part [M1.13]异常的解决方式
查看>>
mask-image进度加载学习
查看>>
UITableView的优化
查看>>
jmeter关于中文乱码显示为问号的问题
查看>>
import pandas_datareader 报错“can't import name is_list_like”
查看>>
4. Median of Two Sorted Arrays
查看>>
Codeforces 785C Anton and Fairy Tale (规律+二分查找)
查看>>
Echarts学习求教
查看>>
PopupMenu介绍
查看>>
Log4j详细介绍(五)----输出地Appender
查看>>
几条高效的分页语句
查看>>
swift 初见-1
查看>>
javascript设计模式-工厂模式(简单工厂)
查看>>
离职之感
查看>>
python基础(二)
查看>>
AutoMapper 使用实践
查看>>
前端页面给指定的div添加遮罩层,并且带有加载中的小旋转图片
查看>>