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 = 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<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 = 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<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 - 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指导教程。

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

(版权所有,转载请标明出处)  转载于http://www.cnblogs.com/potential/archive/2012/11/17/2775141.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。
ArcGIS网络分析是一个功能强大的工具,它可以帮助用户对各种网络进行分析和优化。根据引用,ArcGIS网络分析可以分为传输网络(Network Analyst)和效用网络(Utility Network Analyst)两类。 传输网络主要用于道路、地铁等交通网络分析。在传输网络,汽车和火车等物体可以自由移动,并具有主观选择方向的能力。传输网络解决的问题包括计算之间的最佳距离、多物流派送、寻找设施等。 效用网络主要用于水、电、气等管网的连通性分析。在效用网络,资源通过管道和线路被 passively 从高压向低压输送,不能主观选择方向。效用网络解决的问题包括寻找连通的/不连通的管线、上/下游追踪、寻找环路等。 根据引用和引用,ArcGIS网络分析是基于地理网络模型的,该模型分为几何网络模型和网络数据集模型。几何网络模型是由网络要素构成的,通过限制网络要素在网络内,地理数据库能够自动维护几何网络网络要素之间的拓扑关系。而网络数据集模型是根据资源的流动方向是否确定来划分的。几何网络模型是基于几何一致性的,而网络数据集模型则是根据资源的流动方向来进行分析。 综上所述,ArcGIS网络分析是通过几何网络模型和网络数据集模型对传输网络和效用网络进行分析的工具。具体的分析方法和功能根据不同的网络类型而有所不同。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [arcgis-之网络分析](https://blog.csdn.net/cj9551/article/details/79053881)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [ArcGIS网络分析](https://blog.csdn.net/weixin_34234829/article/details/93704869)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值