ArcGIS.Server.9.3和ArcGIS API for Flex的GeoprocessingServices和最短路径分析(十三)
目的:
1.ArcGIS API for Flex用GeoprocessingServices实现网络分析中的最短路径分析,本例子根据在地图上指定Stops点和Barriers点然后进行最短路径的分析并且把路径分析结果显示在地图中同时在右边的DataGrid中现在最短路径的行车方法。
准备工作:
1.本来例子采用的数据是SanFrancisco数据(ArcTutor\GP Service Examples\DriveTimePolygons),在ArcGIS.Server.9.3发布一个叫SanFranciscoBasemap的Map Service(SanFranciscoBasemap.mxd)。
2.在ArcGIS.Server.9.3发布一个叫GPRouteA的Geoprocessing Service,关于Geoprocessing模型的制作以及Geoprocessing Service的发布设置请参考http://webhelp.esri.com/arcgisserver/9.3/java/index.htm#geoprocessing/guide_-1963186772.htm页面中的Example了,讲述的很详细了。
完成后的效果图:
开始:
1.关于Geoprocessing Service的介绍见http://www.cnblogs.com/hll2008/archive/2008/11/07/1329177.html。
2.启动Flex Builder3新建工程以及引入1.0正式版的ArcGIS API for Flex library的开发包。
3.新建GPRoute.mxml页面,添加Map、ArcGISTiledMapServiceLayer、GraphicsLayer等并且设置相应的属性。具体代码如下:
5.接着在Map控件的上方添加ToggleButtonBar和Button控件,ToggleButtonBar控件用来实现地图漫游、添加stops、添加Barriers的功能切换,Button为进行最短路径分析的按钮。在Map控件的右边添加一个DataGrid用来显示行车走法,代码:
8.接下来还有本篇的主角Geoprocessor了,它的url地址是我们上面发布的GPRouteA的Geoprocessing Service的rest地址:
1.ArcGIS API for Flex用GeoprocessingServices实现网络分析中的最短路径分析,本例子根据在地图上指定Stops点和Barriers点然后进行最短路径的分析并且把路径分析结果显示在地图中同时在右边的DataGrid中现在最短路径的行车方法。
准备工作:
1.本来例子采用的数据是SanFrancisco数据(ArcTutor\GP Service Examples\DriveTimePolygons),在ArcGIS.Server.9.3发布一个叫SanFranciscoBasemap的Map Service(SanFranciscoBasemap.mxd)。
2.在ArcGIS.Server.9.3发布一个叫GPRouteA的Geoprocessing Service,关于Geoprocessing模型的制作以及Geoprocessing Service的发布设置请参考http://webhelp.esri.com/arcgisserver/9.3/java/index.htm#geoprocessing/guide_-1963186772.htm页面中的Example了,讲述的很详细了。
完成后的效果图:
开始:
1.关于Geoprocessing Service的介绍见http://www.cnblogs.com/hll2008/archive/2008/11/07/1329177.html。
2.启动Flex Builder3新建工程以及引入1.0正式版的ArcGIS API for Flex library的开发包。
3.新建GPRoute.mxml页面,添加Map、ArcGISTiledMapServiceLayer、GraphicsLayer等并且设置相应的属性。具体代码如下:
<mx:Canvas width="495" height="396" borderStyle="solid" borderThickness="3" left="10" verticalCenter="14">
<esri:Map id="myMap" logoVisible="false">
<esri:ArcGISTiledMapServiceLayer url="http://jh-53a435fbc0e8/ArcGIS/rest/services/SanFranciscoBasemap/MapServer" />
<esri:GraphicsLayer id="ruteGraphicsLayer" symbol="{sls}" />
<esri:GraphicsLayer id="myGraphicsLayer" graphicAdd="graphicAddHandler(event)" />
</esri:Map>
</mx:Canvas>
4.上面的代码包含了一个 ArcGISTiledMapServiceLayer和二个GraphicsLayer,ruteGraphicsLayer用来显示分析后的路径,myGraphicsLayer用来显示 stops、Barriers点。<esri:Map id="myMap" logoVisible="false">
<esri:ArcGISTiledMapServiceLayer url="http://jh-53a435fbc0e8/ArcGIS/rest/services/SanFranciscoBasemap/MapServer" />
<esri:GraphicsLayer id="ruteGraphicsLayer" symbol="{sls}" />
<esri:GraphicsLayer id="myGraphicsLayer" graphicAdd="graphicAddHandler(event)" />
</esri:Map>
</mx:Canvas>
5.接着在Map控件的上方添加ToggleButtonBar和Button控件,ToggleButtonBar控件用来实现地图漫游、添加stops、添加Barriers的功能切换,Button为进行最短路径分析的按钮。在Map控件的右边添加一个DataGrid用来显示行车走法,代码:
<mx:ToggleButtonBar verticalCenter="-215" itemClick="itemClickHandler(event)" left="10">
<mx:dataProvider>
<mx:Array>
<mx:Object icon="{Pan}" />
<mx:Object icon="{point}" />
<mx:Object icon="{Bbrri}" />
</mx:Array>
</mx:dataProvider>
</mx:ToggleButtonBar>
<mx:Button label="最短路径分析" left="138" verticalCenter="-216" fontSize="12" click="doShortestRoute()"/>
<mx:DataGrid id="Directions" height="396" width="100%" left="513" verticalCenter="14">
<mx:columns>
<mx:DataGridColumn headerText="Directions" dataField="text"/>
</mx:columns>
</mx:DataGrid>
6.接下来添加Draw控件以及点、线的样式设定:
<mx:dataProvider>
<mx:Array>
<mx:Object icon="{Pan}" />
<mx:Object icon="{point}" />
<mx:Object icon="{Bbrri}" />
</mx:Array>
</mx:dataProvider>
</mx:ToggleButtonBar>
<mx:Button label="最短路径分析" left="138" verticalCenter="-216" fontSize="12" click="doShortestRoute()"/>
<mx:DataGrid id="Directions" height="396" width="100%" left="513" verticalCenter="14">
<mx:columns>
<mx:DataGridColumn headerText="Directions" dataField="text"/>
</mx:columns>
</mx:DataGrid>
<esri:InfoSymbol id="ifs">
<esri:infoRenderer>
<mx:Component>
<mx:VBox width="100%" height="100%" backgroundColor="0xEEEEEE" >
<mx:Style>
.ns
{
color: #ff0000;
fontSize: 12;
fontWeight: bold;
}
</mx:Style>
<mx:HBox id="titleBar" width="100%" height="100%" >
<mx:Label text="{data}" styleName="ns">
</mx:Label>
</mx:HBox>
</mx:VBox>
</mx:Component>
</esri:infoRenderer>
</esri:InfoSymbol>
<esri:SimpleMarkerSymbol id="sms" style="x" color="0xFF0000" size="20" alpha="0.9"/>
<esri:SimpleLineSymbol id="sls" style="solid" color="0x0000FF" width="5" alpha="1"/>
7.对于上面中比较复杂的是InfoSymbol的样式设置,这个在前面的文章中也有用到了具体参考:ArcGIS.Server.9.3和ArcGIS API for Flex在MapTips显示饼图数据统计(九) <esri:infoRenderer>
<mx:Component>
<mx:VBox width="100%" height="100%" backgroundColor="0xEEEEEE" >
<mx:Style>
.ns
{
color: #ff0000;
fontSize: 12;
fontWeight: bold;
}
</mx:Style>
<mx:HBox id="titleBar" width="100%" height="100%" >
<mx:Label text="{data}" styleName="ns">
</mx:Label>
</mx:HBox>
</mx:VBox>
</mx:Component>
</esri:infoRenderer>
</esri:InfoSymbol>
<esri:SimpleMarkerSymbol id="sms" style="x" color="0xFF0000" size="20" alpha="0.9"/>
<esri:SimpleLineSymbol id="sls" style="solid" color="0x0000FF" width="5" alpha="1"/>
8.接下来还有本篇的主角Geoprocessor了,它的url地址是我们上面发布的GPRouteA的Geoprocessing Service的rest地址:
<esri:Geoprocessor id="gp" url="http://jh-53a435fbc0e8/ArcGIS/rest/services/GPRouteA/GPServer/CalcShortestRoute" />
9.最后还需要添加一个HTTPService的控件,这个是用来获取路径分析后生成的DIRECTIONS的xml文件的,关于HTTPService的控件可以搜索网络上了非常重要的一个控件。代码:
<mx:HTTPService id="feedRequest" url="" useProxy="false" result="resultHandler(event)" >
</mx:HTTPService>
10.完成界面的代码后接下来开始介绍具体的功能代码,按照事件的执行顺序首先是ToggleButtonBar的itemClick的事件方法itemClickHandler(event),代码很简单了不作解释了:
</mx:HTTPService>
private function itemClickHandler(event:ItemClickEvent):void
{
switch(event.index)
{
case 0:
{
drawToolbar.deactivate();
break;
}
case 1:
{
drawToolbar.activate(Draw.MAPPOINT);
isStops=true;
break;
}
case 2:
{
drawToolbar.activate(Draw.MAPPOINT);
isStops=false;
break;
}
}
}
11.接下来是Draw控件的drawStart事件的drawStartHandler(event)方法,在方法是对前面一次的分析结果显示进行清除操作:
{
switch(event.index)
{
case 0:
{
drawToolbar.deactivate();
break;
}
case 1:
{
drawToolbar.activate(Draw.MAPPOINT);
isStops=true;
break;
}
case 2:
{
drawToolbar.activate(Draw.MAPPOINT);
isStops=false;
break;
}
}
}
private function drawStartHandler(event):void
{
//清除前一次的路径分析以及点的显示
if(p==0)
{
ruteGraphicsLayer.clear();
myGraphicsLayer.clear();
}
}
12.接下来是myGraphicsLayer的graphicAdd事件的graphicAddHandler(event)方法,这个方法是保存stops点和Barrier点 :
{
//清除前一次的路径分析以及点的显示
if(p==0)
{
ruteGraphicsLayer.clear();
myGraphicsLayer.clear();
}
}
private function graphicAddHandler(event:GraphicEvent):void
{
switch(event.graphic.geometry.type)
{
case Geometry.MAPPOINT:
{
if(isStops)//保存Stop点
{
p=p+1;
var object :String = new String(p);
event.graphic.attributes=object;
event.graphic.symbol=ifs;
var graphic:Graphic=new Graphic(event.graphic.geometry);
plist.push(graphic);
}
else//保存Barrier点
{
event.graphic.symbol=sms;
var graphic:Graphic=new Graphic(event.graphic.geometry);
blist.push(graphic);
}
break;
}
}
}
13.接下来是Button控件的click事件的doShortestRoute()方法,这个方法就是进行路径分析:
{
switch(event.graphic.geometry.type)
{
case Geometry.MAPPOINT:
{
if(isStops)//保存Stop点
{
p=p+1;
var object :String = new String(p);
event.graphic.attributes=object;
event.graphic.symbol=ifs;
var graphic:Graphic=new Graphic(event.graphic.geometry);
plist.push(graphic);
}
else//保存Barrier点
{
event.graphic.symbol=sms;
var graphic:Graphic=new Graphic(event.graphic.geometry);
blist.push(graphic);
}
break;
}
}
}
//进行路径分析
private function doShortestRoute():void
{
if(plist.length>1 && blist.length>0)
{
//设置光标状态
CursorManager.setBusyCursor();
//Stops参数
var featureSet:FeatureSet = new FeatureSet(plist);
//Barriers参数
var featureSet2:FeatureSet = new FeatureSet(blist);
var params:Object = {
"Input_locations":featureSet,"InputBarriers":featureSet2
};
//进行分析成功调用onResult方法,失败调用onFault方法
gp.execute(params, new AsyncResponder(onResult,onFault));
}
else
{
Alert.show("至少需要2个Stop点和1个Barrier点!");
}
}
14.对于上面的这段代码主要就是设置Geoprocessor的输入参数了,这个根据具体的model进行设置了,本例的最短路径的model有2个输入参数分别是用来输入stops点和Barrier点:
private function doShortestRoute():void
{
if(plist.length>1 && blist.length>0)
{
//设置光标状态
CursorManager.setBusyCursor();
//Stops参数
var featureSet:FeatureSet = new FeatureSet(plist);
//Barriers参数
var featureSet2:FeatureSet = new FeatureSet(blist);
var params:Object = {
"Input_locations":featureSet,"InputBarriers":featureSet2
};
//进行分析成功调用onResult方法,失败调用onFault方法
gp.execute(params, new AsyncResponder(onResult,onFault));
}
else
{
Alert.show("至少需要2个Stop点和1个Barrier点!");
}
}
Parameter: Input_locations
Data Type: GPFeatureRecordSetLayer
Display Name: Input locations
Direction: esriGPParameterDirectionInput
Default Value: Geometry Type: esriGeometryPoint
Parameter: InputBarriers
Data Type: GPFeatureRecordSetLayer
Display Name: InputBarriers
Direction: esriGPParameterDirectionInput
Default Value:Geometry Type: esriGeometryPoint
15.在执行完成doShortestRoute()方法后成功调用onResult方法,失败调用onFault方法:
Data Type: GPFeatureRecordSetLayer
Display Name: Input locations
Direction: esriGPParameterDirectionInput
Default Value: Geometry Type: esriGeometryPoint
Parameter: InputBarriers
Data Type: GPFeatureRecordSetLayer
Display Name: InputBarriers
Direction: esriGPParameterDirectionInput
Default Value:Geometry Type: esriGeometryPoint
//成功后结果显示包括路径显示以及用HTTPService去获取分析生成的DIRECTIONS的xml用来显示行车走法
private function onResult(gpResult:ExecuteResult,token:Object = null):void
{
//取消光标忙碌显示
CursorManager.removeBusyCursor();
//获取路径进行显示
var pv : ParameterValue = gpResult.parameterValues[0];
var fs : FeatureSet = pv.value as FeatureSet;
ruteGraphicsLayer.graphicProvider = fs.features;
//获取DIRECTIONS的xml路径
var pv2 : ParameterValue = gpResult.parameterValues[1];
var url:String=pv2.value.url as String;
feedRequest.url=url;
//请求xml
feedRequest.send();
}
//Geoprocessor失败显示失败信息右边的DataGrid中
private function onFault(info:Object, token:Object = null):void
{
CursorManager.removeBusyCursor();
Alert.show(info.toString());
}
16.在上面的onResult方法中获取分析结果,本例子model有2个输出参数分别为最多路径的图形以及DIRECTIONS的xml文件:
private function onResult(gpResult:ExecuteResult,token:Object = null):void
{
//取消光标忙碌显示
CursorManager.removeBusyCursor();
//获取路径进行显示
var pv : ParameterValue = gpResult.parameterValues[0];
var fs : FeatureSet = pv.value as FeatureSet;
ruteGraphicsLayer.graphicProvider = fs.features;
//获取DIRECTIONS的xml路径
var pv2 : ParameterValue = gpResult.parameterValues[1];
var url:String=pv2.value.url as String;
feedRequest.url=url;
//请求xml
feedRequest.send();
}
//Geoprocessor失败显示失败信息右边的DataGrid中
private function onFault(info:Object, token:Object = null):void
{
CursorManager.removeBusyCursor();
Alert.show(info.toString());
}
Parameter: Routes
Data Type: GPFeatureRecordSetLayer
Display Name: Routes
Direction: esriGPParameterDirectionOutput
Default Value: Geometry Type: esriGeometryPolyline
Parameter: Text_Directions
Data Type: GPDataFile
Display Name: Text Directions
Direction: esriGPParameterDirectionOutput
17.onResult方法最后会调用HTTPService控件获取DIRECTIONS的xml文件把内容显示在右边的DataGrid中:
Data Type: GPFeatureRecordSetLayer
Display Name: Routes
Direction: esriGPParameterDirectionOutput
Default Value: Geometry Type: esriGeometryPolyline
Parameter: Text_Directions
Data Type: GPDataFile
Display Name: Text Directions
Direction: esriGPParameterDirectionOutput
//获取DIRECTIONS的xml文件内容后显示在
private function resultHandler(event: ResultEvent ):void
{
var rlist:ArrayCollection=new ArrayCollection();
if(plist.length>2)
{
var nlist:ArrayCollection= event.result.DIRECTIONS.ROUTE.PATH;
for(var i:int=0;i<nlist.length;i++)
{
var nlist2:ArrayCollection=nlist[i].DIRECTION;
for(var j:int=0;j<nlist2.length;j++)
{
var nlist3:ArrayCollection=nlist2[j].STRINGS.STRING;
rlist.addItem(nlist3[0]);
}
}
}
else
{
var nlist:ArrayCollection= event.result.DIRECTIONS.ROUTE.PATH.DIRECTION;
for(var i:int=0;i<nlist.length;i++)
{
var nlist2:ArrayCollection=nlist[i].STRINGS.STRING;
rlist.addItem(nlist2[0]);
}
}
Directions.dataProvider=rlist;
//清除stops和Barriers
plist=new Array();
blist=new Array();
p=0;
}
18.这样就完成了最短路径分析的例子。private function resultHandler(event: ResultEvent ):void
{
var rlist:ArrayCollection=new ArrayCollection();
if(plist.length>2)
{
var nlist:ArrayCollection= event.result.DIRECTIONS.ROUTE.PATH;
for(var i:int=0;i<nlist.length;i++)
{
var nlist2:ArrayCollection=nlist[i].DIRECTION;
for(var j:int=0;j<nlist2.length;j++)
{
var nlist3:ArrayCollection=nlist2[j].STRINGS.STRING;
rlist.addItem(nlist3[0]);
}
}
}
else
{
var nlist:ArrayCollection= event.result.DIRECTIONS.ROUTE.PATH.DIRECTION;
for(var i:int=0;i<nlist.length;i++)
{
var nlist2:ArrayCollection=nlist[i].STRINGS.STRING;
rlist.addItem(nlist2[0]);
}
}
Directions.dataProvider=rlist;
//清除stops和Barriers
plist=new Array();
blist=new Array();
p=0;
}