ArcGIS网络分析之Silverlight客户端路径分析(三)

原文:ArcGIS网络分析之Silverlight客户端路径分析(三)

首先贴上最终的效果图:

a.路径查询

2.最近设施点查询

3.服务区分析

说明:

1.以上的示例使用的数据是随意在ArcMap中创建的数据,也就是之前博文新建的数据,这里的单位和比例尺并不是实际的单位和比例尺。所以和底图的显示不一致,这里的底图只是为了增加显示的效果。

2.以上所以的实现基于之前的两篇关于网络分析的博文,在此推荐看一看。

3.以上示例的具体细节将会分别为大家讲解,欢迎大家相互交流,批评指正。

一.路径分析服务概述

路径分析服务可以为Silverlight
WEBGIS提供最佳路径的选择功能,用户指定两个点便可以查询出两点之间的最佳路径,同时用户还可以考虑不同的因素来找到最佳的路径,例如设置障碍点,阻抗等。使用路径分析功能时需要使用ArcGIS
Api for
Silverlight中的TouteTask类。同时还需提供网络分析服务中路径分析图层的地址(即上一篇博文中我们发布的网络分析服务中路径服务的地址。其地址的一般格式是:

http://<GIS服务器地址>/ArcGIS/rest/services/<网络分析服务名称>/NAServer/Route.

关于网络分析服务的发布在之前的博文中已经详细说明,读者可参考之前的博文。

二、路径分析服务的实现过程

这里我初步将实现的过程分为一下几步:

a.实例化TouteTask变量,指定路径服务的地址RouteTask是实现路径分析的重中之重。同时还可以声明三个图层:一个图层用来绘制事件点,一个用来绘制障碍(点,线,面),一个用来绘制所得的路径,并进行实例化。

例如:

声明一个RouteTask

 RouteTask routeTask = new RouteTask("http://qzj-pc/ArcGIS/rest/services/NetworkAnaysisMap/NAServer/Route");//最短路径服务Task

声明三个GraphicsLayer:

        GraphicsLayer stopsGraphicsLayer;//停靠点或事件点图层
GraphicsLayer barriesGraphicsLayer;//障碍物图层
GraphicsLayer RoutegraphicsLayer;//查询返回的路径图层

在Map空间的Load事件中指定GraphicsLayer到相应的图层:


 private void MyMap_Loaded(object sender, RoutedEventArgs e)
{
stopsGraphicsLayer = MyMap.Layers["MyStopGraphicsLayer"] as GraphicsLayer;
barriesGraphicsLayer = MyMap.Layers["MyBarriesGraphicsLayer"] as GraphicsLayer;
RoutegraphicsLayer = MyMap.Layers["MyRouteLayer"] as GraphicsLayer;
}

以上过程需要在在XAML中添加相应的GraphicsLayer声明。


 <esri:Map Background="White" HorizontalAlignment="Stretch" x:Name="MyMap" VerticalAlignment="Stretch" WrapAround="True" 
Loaded="MyMap_Loaded" MouseClick="MyMap_MouseClick" IsLogoVisible="False">
<esri:Map.Layers>
<esri:LayerCollection>
<esri:ArcGISTiledMapServiceLayer ID="BaseMap"
Url="http://www.arcgisonline.cn/ArcGIS/rest/services/ChinaOnlineStreetGray/MapServer"/>
<esri:ArcGISDynamicMapServiceLayer ID="ChinaBaseMap"
Url="http://qzj-pc/ArcGIS/rest/services/NetworkAnaysisMap/MapServer"
InitializationFailed="ArcGISDynamicMapServiceLayer_InitializationFailed" />
<esri:GraphicsLayer ID="MyRouteLayer"/>
<esri:GraphicsLayer ID="MyStopGraphicsLayer"/>
<esri:GraphicsLayer ID="MyBarriesGraphicsLayer"/>
</esri:LayerCollection>
</esri:Map.Layers>
</esri:Map>

b.注册RouteTask的SolveCompleted以及Failed事件例如:

注册事件:

routeTask.SolveCompleted += new EventHandler<RouteEventArgs>(routeTask_SolveCompleted);
routeTask.Failed += new EventHandler<TaskFailedEventArgs>(Task_Failed);



private void routeTask_SolveCompleted(object sender, RouteEventArgs e)
{
}
private void Task_Failed(object sender, TaskFailedEventArgs e)
{
MessageBox.Show("求解失败" + e.Error.ToString());
}

c.添加用于计算路径的点,并设置相应的Symbol.

例如:我们点击地图就添加一个点,示例代码如下:


    private void MyMap_MouseClick(object sender, Map.MouseEventArgs e)
{
if (tabControl1.SelectedIndex != 0)
StopsRadioButton.IsChecked = true;
StopsGraphic = new Graphic();
if (StopsRadioButton.IsChecked == true)
{
StopsGraphic.Symbol = LayoutRoot.Resources["MyStopsMarkerSymbol"] as Symbol;
StopsGraphic.Geometry = new MapPoint(e.MapPoint.X, e.MapPoint.Y);
addFacilityName.Show();
}
else
{
StopsGraphic.Symbol = LayoutRoot.Resources["MyBarriesMarkerSymbol"] as Symbol;
StopsGraphic.Geometry = new MapPoint(e.MapPoint.X, e.MapPoint.Y);
StopsGraphic.Selected = true;
barriesGraphicsLayer.Graphics.Add(StopsGraphic);
}
}

代码说明:addFacilityName表示的是一个ChildWindow,如下图的所示:

addFacilityName是AddFacilitiesName的一个实例用来给添加的停靠点增加一个Name属性,界面如下:

ChildWindow中的关键代码:

在AddFacilitiesName.xaml.cs中定义一个事件:

public event EventHandler OnAddFacilityName;

该事件当用户点击确定是触发,即表示用户确定添加一个停靠点。

 private void OKButton_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = true;
OnAddFacilityName(this, new EventArgs());
}

然后在MainPage中注册OnAddFacilityName的事件,并在其事件的响应函数中完成停靠点的最终添加工作。
声明AddFacilitiesName的一个实例:

public AddFacilitiesName addFacilityName = new AddFacilitiesName();

注册OnAddFacilityName事件:

 addFacilityName.OnAddFacilityName += new EventHandler(FacilityName_OnAddFacilityName);

在事件回调函数中完成点的添加工作:


 private void FacilityName_OnAddFacilityName(object sender, EventArgs e)
{
//清空停靠点的属性,否则当再次添加Name属性时,则会因为存在Name属性而报错
StopsGraphic.Attributes.Clear();
//停靠点样式中显示的数字与该属性进行绑定
StopsGraphic.Attributes.Add("StopNumber", stopsGraphicsLayer.Graphics.Count + 1);
//获取ChildWindow输入的名称,并添加Name属性
StopsGraphic.Attributes.Add("Name", addFacilityName.NameTextBox.Text.ToString());
//将停靠点添加到当前图层中
stopsGraphicsLayer.Graphics.Add(StopsGraphic);
}

以上代码使用到了在XAML中定义的资源文件,用来描述停靠点和障碍点的样式。
示例代码如下:


   <esri:SimpleMarkerSymbol x:Key="MyStopsMarkerSymbol" Size="20" Style="Circle" Color="Salmon" >
<esri:SimpleMarkerSymbol.ControlTemplate>
<ControlTemplate>
<Grid>
<Ellipse Fill="{Binding Symbol.Color}" Width="{Binding Symbol.Size}" Height="{Binding Symbol.Size}" S
troke="Black" StrokeThickness="1" />
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center"
Text="{Binding Path=Attributes[StopNumber]}"
FontSize="9" Margin="0" FontWeight="Bold" Foreground="Black" />
</Grid>
</ControlTemplate>
</esri:SimpleMarkerSymbol.ControlTemplate>
</esri:SimpleMarkerSymbol>
<esri:SimpleMarkerSymbol x:Name="MyBarriesMarkerSymbol" Color="#FF833232" Style="Square" Size="18"/>

同时我们在这里再定义一下路径的Graphic样式:


  <esri:SimpleLineSymbol x:Key="RouteRenderer">
<!--<esri:SimpleRenderer.Symbol>-->
<!--<esri:LineSymbol>-->
<esri:LineSymbol.ControlTemplate>
<ControlTemplate>
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard RepeatBehavior="Forever">
<DoubleAnimation BeginTime="0:0:0" Storyboard.TargetName="Element"
Storyboard.TargetProperty="StrokeDashOffset"
To="1000" Duration="0:3:0" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<!--For polyline and polygon template, a Path
element with the name "Element" is required-->
<Path x:Name="Element" StrokeDashArray="2,1" StrokeDashOffset="0"
Stroke="#990000FF" StrokeThickness="8" />
</Grid>
</ControlTemplate>
</esri:LineSymbol.ControlTemplate>
<!--</esri:LineSymbol>-->
<!--</esri:SimpleRenderer.Symbol>-->
</esri:SimpleLineSymbol>

d.设置路径服务的输入参数
  
路径服务的参数:RouteParameters,继承自BaseRouteParameters。RouteParameters的主要成员有:





































成员参数名


参数描述

DirectionsLanguage 计算方向时使用的语言,默认与路径网绚图层的设置一致,但是NAServer只安装了en_US,其他语言需要管理员自行安装。
DirectionsLengthUnits 计算方向时使用的长度单位。默认与路径网络图层的设置一致。可用的值包括esriFeet,esriKilometers,
esriMeters,esriMile,esriNauticalMiles和esriYards。
DirectionsTimeAttribute 用于计算驾驶时间的网绚属性。默认与路径网络图层的设置一致。
ReturnDirections 是否返回方向。
ReturnRoutes 是否返回路径
FindBestSequence 如果为true,解析器将优化路径中停靠点(Stop)的顸序(如果preserveFirstStop和preserveLastStop为true,则不考虑起点和终点)。
StartTime 指定路径(从第一个停靠点)开始的时间。
Stops 路径分析时的停靠点。可以使DataLayer或FeatureSet。
 Barriers 路径分析时的障碍点。可以使DataLayer或FeatureSet。
UseHierarchy 是否在分析中使用网络的等级属性。默认与路径网络图层的设置一致。

示例代码:


 RouteParameters routeParameters = new RouteParameters()
{
Stops = stopsGraphicsLayer,
Barriers = barriesGraphicsLayer,
OutSpatialReference = MyMap.SpatialReference,
ReturnDirections = true,
FindBestSequence = true,
PreserveFirstStop = true,
PreserveLastStop = true,
};

这里需要注意:如果在构建网络时没有构建等级属性,这里一定不要使用等级属性否则会报错,当在构建网络时设置了等级属性,那么这里才可以使用等级设置.

e.开始计算路径

  if (routeTask.IsBusy)
routeTask.CancelAsync();
routeTask.SolveAsync(routeParameters);

f. 在Completed事件的回调函数中获取结果(包含路径和方向指南)

当执行结果完成后RouteTask将最后的结果传递给RouteEventArgs的RouteResults属性,RouteResults是RouteResult的集合,对于路径查询来说,最后的RouteResults集合只有一个RouteResult。RouteResult的主要成员如下:




















主要成员参数名



成员描述


Directions 如果RouteParameters.ReturnDirections为true,则迒回路径方向(DirectionsFeatureSet类实例)。
Route 如果returnRoutes为true并且outputLines属性不是esriNAOutputLineNone,则将返回路径图形(polyline)。
RouteName 路径名称。
Stops 停靠点集合。

RouteResult中的Route表示一个Graphic,也就是我们最后的路径结果。所以这里我们想获得最佳的路径结果,只需要取得Route,并设置其样式,最后添加到地图中即可。

RouteResult中的Directions表示路径中包含的方向指南,Drirections的类型是DirectionsFeatureSet,其成员如下:




























主要成员参数名


成员描述

Extent 路径的范围。
RouteID 获得服务器返回的路径ID
RouteName RouteParameters.Stops中指定的名称。
TotalDriveTime 路径时间驾驶时间。
TotalLength 路径总长度。
TotalTime 路径总通行时间。
MergedGeometry 表示整个路径的单条线。

DirectionsFeatureSet继承自FeatureSet。所以Drirections实际上也是一系列的Graphic.并且这些Graphic包含了三个重要的属性:
















Drirections中Graphic的属性



属性描述


text 对某一段路径的方向描述。
length 表示某一段路径的长度
time 表示某一段路径的所需的时间

所以我们现在只需要将上述所有信息收集起来并合理编排就能够得到路径和方向指南。

示例代码如下:


    private void routeTask_SolveCompleted(object sender, RouteEventArgs e)
{
DirectionStackPanel.Children.Clear();//清空路径指南中的所有方向提示
RoutegraphicsLayer.Graphics.Clear();//清空之前的路径图层
RouteResult routeResult = e.RouteResults[0];//最佳路线查询只有一个结果,因此数组的长度是1.
routeResult.Route.Symbol = LayoutRoot.Resources["RouteRenderer"] as SimpleLineSymbol;//设置路径的样式
RoutegraphicsLayer.Graphics.Add(routeResult.Route);//将路径添加到当前的地图中
int i = 1;
foreach (Graphic g in routeResult.Directions)
{
StringBuilder direction = new StringBuilder();
//设置方向描述的格式:<i>.<描述>
direction.AppendFormat("{0}. {1}", i, g.Attributes["text"]);
if (i > 1 && i < routeResult.Directions.Features.Count)
{
//由于当在起点或中间停靠点时,Graphic中的length属性为0
//因此在执行强制转换时会出错,
//同时也是格式化输出,在停靠点不输出时间和长度属性,每一个停靠点都看作是一个起点
if (Convert.ToDecimal(g.Attributes["length"])!= 0)
{
//当length属性不为0时,在路径指南中显示出来
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"));
}
}
//显示路线提示的Panel
DirectionStackPanel.Children.Add(new TextBlock()
{
Text = direction.ToString(),
Margin = new Thickness(4)
});
i++;
}
DirectionStackPanel.Children.Add(new TextBlock()
{
Text = string.Format(" 总路程为:{0}千米\n\n 总时间为:{1}分钟", routeResult.Directions.TotalLength.ToString("#0.000"),
routeResult.Directions.TotalDriveTime.ToString("#0.00"))
});
}

到此位置所关于路径服务就已结束。下一篇将讲解如何实现最近设施点分析。
本文参考了ArcGIS API For
Silverlight的官网的Network Analysis的例子,以及ESRI中国的ArcGIS Api for Silverlight的帮助文档。

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

ArcGIS网络分析之Silverlight客户端路径分析(三),布布扣,bubuko.com

时间: 2024-10-13 11:56:58

ArcGIS网络分析之Silverlight客户端路径分析(三)的相关文章

ArcGIS网络分析之Silverlight客户端最近设施点分析(四)

原文:ArcGIS网络分析之Silverlight客户端最近设施点分析(四) 在上一篇中说了如何实现最近路径分析,本篇将讨论如何实现最近设施点分析. 最近设施点分析实际上和路径分析有些相识,实现的过程基本一致,不同的是参数的设置,选用的分析图层为最近设施点网络分析图层,一般形式为: http://<服务器名或ip地址>/ArcGIS/rest/services/<地图服务名称>/NAServer/<最近设施点分析图层名称> 在ArcGIS Api for Silverl

ArcGIS API for Silverlight 调用GP服务加载等值线图层

原文:ArcGIS API for Silverlight 调用GP服务加载等值线图层 第二篇.Silverlight客户端调用GP服务 利用ArcGIS API for Silverlight实现GP服务调用,这里的雨量数据是通过一个WebService获取而来,主要信息是雨量站点的经纬度坐标值和某个时间段内的降雨量值三个主要字段. 以下是核心代码部分: <UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/pr

使用ArcGIS API for Silverlight实现地形坡度在线分析

原文:使用ArcGIS API for Silverlight实现地形坡度在线分析 苦逼的研究生课程终于在今天结束了,也许从今以后再也不会坐在大学的课堂上正式的听老师讲课了,接下来的时间就得开始找工作了.....前段时间一直比较忙,上课,考试,论文,以及联系实习单位...现在就差实习还没有着落了. 前些天帮一网友做了个在线坡度分析的例子,大概的功能就是勾选任意的地形区域,然后实现Web端的地形坡度分析和可视化显示,效果图如下: 实现的基本思路大致分为以下三部分: 1.在ArcMap中建立坡度求解

浅析ArcGis API for Silverlight查询

一.ArcGis API for Silverlight 简介    ArcGIS API for Silverlight是由美国Esri公司推出的,用于在Silverlight平台上开发WebGIS应用的一套编程接口.ArcGIS API for Silverlight通过REST接口访问ArcGIS Server发布的地图服务.影像服务.几何服务.地理处理服务.要素服务.网络服务等,还可以访问OGC标准的WMS.WFS.WCS等服务,也可以访问Bing地图服务.主要功能有:1. 空间数据展示

ArcGIS API for Silverlight 调用GP服务准备---GP模型建立、发布、测试

原文:ArcGIS API for Silverlight 调用GP服务准备---GP模型建立.发布.测试 第一篇.GP降雨量等值线建模.发布及测试 在水利.气象等行业中,要在WebGIS中实现空间分析功能,如绘制等值线.等高线.等直面.缓冲区等都是经常遇到,经过一段时间的学习和研究,查阅ESRI文档,请教他人,终于可以说是初步实现了等值线功能,这里记录下来详细的操作步骤和图片说明,一方面是对此次努力的总结,另一方面希望也能给后来用到这方面的其他同志们,起个抛砖引玉的作用. 下一篇是关于Silv

使用Socket通信实现Silverlight客户端实时数据的获取(模拟GPS数据,地图实时位置)

原文:使用Socket通信实现Silverlight客户端实时数据的获取(模拟GPS数据,地图实时位置) 在上一篇中说到了Silverlight下的Socket通信,在最后的时候说到本篇将会结合地图.下面就来看看本文实现的功能: Silverlight 与服务器利用Socket通讯,实时从服务器获取数据(本文中的数据是地理坐标),由于没有GPS,所以本文在服务器写了一个构造新坐标的函数(本文是一个三角函数),然后利用Timer组件,实时调用,得到新的坐标,并将新的坐标发送给客户端,客户端接收到发

ArcGIS API for Silverlight 绘制降雨路径动画

原文:ArcGIS API for Silverlight 绘制降雨路径动画 #region 降雨动画演示 2014-04-16 List<Graphic> graphics = new List<Graphic>(); int INDEX = 0; MapPoint GLOBAL = new MapPoint(); //保存上一次绘制降雨圈的点信息 2014-04-16 int INDEX_2 = 0; //控制是否是第一次绘制降雨圈 /// <summary> //

ArcGIS 网络分析[1] 介绍与博文目录【更新中】

网络分析是个热点,理论上是属于计算机图形学和数据结构的,GIS以此为基础做出应用. 以下列举本人在学习中遇到的网络分析问题与经验总结. 平台:Windows 10操作系统,ArcGIS for Desktop 10.2或更高版本 用到的软件和SDK:VisualStudio 2012或更高版本.ArcGIS Objects 10.2或更高版本.Microsoft.NET Framework 3.5或更高版本 [网络分析介绍] [博文目录] 1. ArcGIS 网络分析[2] 利用自定义基础数据创

ArcGIS API for Silverlight加载google地图(后续篇)

原文:ArcGIS API for Silverlight加载google地图(后续篇) 之前在博客中(http://blog.csdn.net/taomanman/article/details/8019687)提到的加载google地图方案,因为google地址问题,看不到图了,发现是url地址变换造成的. 现将如下三个类公布出来,源码如下: using System; using System.Net; using System.Windows; using System.Windows.