ArcGIS网络分析之Silverlight客户端最近设施点分析(四)
原文:ArcGIS网络分析之Silverlight客户端最近设施点分析(四)
在上一篇中说了如何实现最近路径分析,本篇将讨论如何实现最近设施点分析。
最近设施点分析实际上和路径分析有些相识,实现的过程基本一致,不同的是参数的设置,选用的分析图层为最近设施点网络分析图层,一般形式为:
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。
例如本文发布的最近设施点的网络分析图层地址为:

http://localhost/ArcGIS/rest/services/NetworkAnaysisMap/NAServer/ClosestFacility
实例化RouteTask
RouteTask closestFacilityTask = new RouteTask("http://qzj-pc/ArcGIS/rest/services/NetworkAnaysisMap/NAServer/ClosestFacility");//最近设施点Task
这里在之前的博文中已经说了网络分析图层的建立和发布。在此不再讨论。
2.注册RouteTask的完成和失败事件
注册事件:
closestFacilityTask.SolveClosestFacilityCompleted += new EventHandler<RouteEventArgs>(closestFacilityTask_SolveClosestFacilityCompleted);
closestFacilityTask.Failed += new EventHandler<TaskFailedEventArgs>(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 = ,
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<object>(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 = ;
foreach (Graphic g in routeResult.Directions)
{
StringBuilder direction = new StringBuilder();
direction.AppendFormat("{0}. {1}", i, g.Attributes["text"]);
if (i > && 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()
});
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 = ;
private void RouteTree_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> 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 - ].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 - ].Symbol = LayoutRoot.Resources["RouteRenderer"] as SimpleLineSymbol;
//将本次点击的所以赋给OldIndex.
OldIndex = currentIndex - ;
}
这样所有的工作基本就已经完成了。下面是整体效果图:

注:以上内容参考了ERSI官网例子,以及ESRI中国编写的ArcGIS Api For Silverlight指导教程。
下一篇将讲解服务区分析的实现过程,欢迎关注!
(版权所有,转载请标明出处)
ArcGIS网络分析之Silverlight客户端最近设施点分析(四)的更多相关文章
- ArcGIS网络分析之Silverlight客户端路径分析(三)
原文:ArcGIS网络分析之Silverlight客户端路径分析(三) 首先贴上最终的效果图: a.路径查询 2.最近设施点查询 3.服务区分析 说明: 1.以上的示例使用的数据是随意在ArcMap中 ...
- 【原创】Silverlight客户端发起WebRequest请求分析
Silverlight网站部署后,客户端浏览器访问的时候会 下载 网站的xap文件包等信息,把程序代码放到本地执行,因为本地机器上安装了silverlight运行库. 所以如果silverlight前 ...
- ArcGIS 网络分析[2.3] 最近设施点
什么是最近设施点? 仍然举一个生动形象例子说明. 我在大街的某一个点儿上,我急需上厕所,问:我3分钟内能到的最近的厕所在哪? 这就是最近设施点分析(ClosestFacility)--给定搜索半径,基 ...
- ArcGIS API for Silverlight 调用GP服务加载等值线图层
原文:ArcGIS API for Silverlight 调用GP服务加载等值线图层 第二篇.Silverlight客户端调用GP服务 利用ArcGIS API for Silverlight实现G ...
- ArcGIS API for Silverlight开发入门
你用上3G手机了吗?你可能会说,我就是喜欢用nokia1100,ABCDEFG跟我 都没关系.但你不能否认3G是一种趋势,最终我们每个人都会被包裹在3G网络中.1100也不是一成不变,没准哪天为了打击 ...
- ArcGIS API for Silverlight 使用GP服务实现要素裁剪功能
原文:ArcGIS API for Silverlight 使用GP服务实现要素裁剪功能 昨天一QQ好友问了一个关于裁剪的问题,感觉自己也没有帮上什么忙,之后自己做了一个裁剪的例子,不过在做这个例子的 ...
- 使用Socket通信实现Silverlight客户端实时数据的获取(模拟GPS数据,地图实时位置)
原文:使用Socket通信实现Silverlight客户端实时数据的获取(模拟GPS数据,地图实时位置) 在上一篇中说到了Silverlight下的Socket通信,在最后的时候说到本篇将会结合地图. ...
- 使用ArcGIS API for Silverlight实现地形坡度在线分析
原文:使用ArcGIS API for Silverlight实现地形坡度在线分析 苦逼的研究生课程终于在今天结束了,也许从今以后再也不会坐在大学的课堂上正式的听老师讲课了,接下来的时间就得开始找工作 ...
- ArcGIS 网络分析[0] 介绍与博文目录【更新中】
网络分析是个热点,理论上是属于计算机图形学和数据结构的,GIS以此为基础做出应用. 以下列举本人在学习中遇到的网络分析问题与经验总结. 1. 软件平台及数据准备 平台:Windows 10 操作系统, ...
随机推荐
- [LeetCode53]Maximum Subarray
问题: Find the contiguous subarray within an array (containing at least one number) which has the larg ...
- NET5实践:项目创建-结构概述-程序运行-发布部署
ASP.NET5实践01:项目创建-结构概述-程序运行-发布部署 1.项目创建 ASP.NET5项目模板有三种: 新建项目: 选择模板: 2.结构概述 References对应配置是project ...
- 【C语言探索之旅】 第三课:你的第一个程序
内容简介 1.课程大纲 2.第一部分第三课:你的第一个程序 3.第一部分第四课预告:变量的世界 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编写三个 ...
- 会员卡管理系统技术解析(十八)Timer定时监听
会员卡管理系统技术解析(十八)Timer定时监听 在web应用中,有时候客户须要一些定时程序.不须要客户自己去操作.而是由应用程序自行触发(代理)运行某些操作. 这个时候监听与定时器的配合使用就基本能 ...
- 【Swift】学习笔记(四)——设置(Collection)
Swift和其他语言也提供了两种类型的集合:数组和字典 数组:数组用来按顺序存储同样类型的数据,swift规定它是类型安全的,每个数组都有自己的类型也就是其它语言所说的泛型. 创建数组: 1.var ...
- iOS 中国排序
这里分享一个中国某种方便的方法,我们放在一起的人脉资源后,方便的类别,使用自己的包, 此处所使用的方法贴,源代码可以在本文的结尾下载. 要记得加头文件 #import "NSArray+So ...
- StackExchange.Redis 使用 - 事件(五)
ConnectionMultiplexer 可以注册如下事件 ConfigurationChanged - 配置更改时 ConfigurationChangedBroadcast - 通过发布订阅更新 ...
- 新RSS reader
阅读之前采取正确的方法,但是非常不介意,没有收到订阅很大. 走到今天 http://www.feedspot.com 2014/11/8追加:用下来感觉不错. feedspot 的相关快捷键例如以下: ...
- 3D-HEVC的TAppDecorder
一.点击项目右键设为启动项目. 二.配置文件 右键点击属性->点配置属性的Debugging,在command arguments一栏填上编码时生成的.bit文件和希望解码后文件的命名,在wor ...
- Path和ClassPath差异
1.Path角色 Path它用于指定Java路径的命令,当我们想编译Java当需要使用的程序javac.exe并运行.class当文件需要使用java.exe,此时Path设置的路径就发生作用了.由于 ...