路径分析,可以拖动上面的节点,动态修改
2011-08-28 14:25
393 查看
Flex下路径分析随机拖动,实现了类似Google map中能够拖动路径并重新实时计算的效果。为了减轻客户端与服务器端的不断交互,因为事实上用户拖动时候并非需要每一步都实时计算,而是在某一点停留超过一给定时间的时候才会重新计算,因此在程序中设置了一个Timer,如果鼠标停留在某一位置超过给定时间,就会向服务器端发送计算的请求,并重新绘制结果。
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:esri="http://www.esri.com/2008/ags"> <mx:Script> <![CDATA[ import com.esri.ags.tasks.DirectionsFeatureSet; import com.esri.ags.layers.GPResultImageLayer; import com.esri.ags.geometry.MapPoint; import mx.controls.Alert; import com.esri.ags.tasks.RouteResult; import com.esri.ags.Graphic; import com.esri.ags.events.MapMouseEvent; import com.esri.ags.events.RouteEvent; import com.esri.ags.tasks.FeatureSet; import mx.rpc.events.FaultEvent; [Bindable] private var stops:FeatureSet = new FeatureSet([]); private var lastRoute:Graphic; private var routeOverStop:Graphic = null; private var moveRoutePoint:Graphic = null; private var coorComTimer:Timer = new Timer(500); private var routeOverStart:Boolean = false; [Bindable] private var directionsFS:DirectionsFeatureSet; private var segmentGraphic:Graphic; private const NL:String = "\n"; private function mapClickHandler(event:MapMouseEvent):void { if (stops.features.length >= 2) return; var stop:Graphic = new Graphic(event.mapPoint, stopSymbol); graphicsLayer.add(stop); if (stops.features.length < 2) stops.features.push(stop); else { var endstop:Graphic = stops.features.pop(); stops.features.push(stop); stops.features.push(endstop); } if (stops.features.length > 1) { routeTask.solve(routeParams); } } private function routeMouseOverHandler(event:MouseEvent):void { lastRoute.symbol = routeMouseOverSymbol; var mapPt:MapPoint = map.toMapFromStage(event.stageX, event.stageY); var overStop:Graphic = new Graphic(mapPt, routeOverSymbol); graphicsLayer.remove(routeOverStop); routeOverStop = overStop; graphicsLayer.remove(moveRoutePoint); graphicsLayer.add(routeOverStop); map.panEnabled = false; } private function routeMouseOutHandler(event:MouseEvent):void { graphicsLayer.remove(routeOverStop); routeOverStop = null; map.panEnabled = true; } private function mouseDownHandler(event:MouseEvent):void { if (routeOverStop == null) return; routeOverStart = true; //Alert.show("Mousedown"); coorComTimer.addEventListener(TimerEvent.TIMER, coorCompare); map.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler); map.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler); } private function mouseMoveHandler(event:MouseEvent):void { lastRoute.symbol = routeSymbol; var mapPt:MapPoint = map.toMapFromStage(event.stageX, event.stageY); var overStop:Graphic = new Graphic(mapPt, routeOverSymbol); graphicsLayer.remove(moveRoutePoint); moveRoutePoint = overStop; graphicsLayer.remove(routeOverStop); graphicsLayer.add(moveRoutePoint); if (stops.features.length == 2) { var endstop:Graphic = stops.features.pop(); stops.features.push(moveRoutePoint); stops.features.push(endstop); } else { if (routeOverStart) { var endstop:Graphic = stops.features.pop(); stops.features.push(moveRoutePoint); stops.features.push(endstop); routeOverStart = false; } else { var endfirststop:Graphic = stops.features.pop(); var endsecondstop:Graphic = stops.features.pop(); stops.features.push(moveRoutePoint); stops.features.push(endfirststop); } } coorComTimer.stop(); coorComTimer.start(); } private function coorCompare(event:TimerEvent):void { if (stops.features.length > 1) { routeTask.solve(routeParams); } } private function mouseUpHandler(event:MouseEvent):void { var i:int = 1; var textCntl:Text; theDirections.removeAllChildren(); for each (var feature:Graphic in directionsFS.features) { textCntl = new Text(); textCntl.percentWidth = 100; textCntl.selectable = false; textCntl.text = i + ". " + feature.attributes.text; if (i > 1 && i < directionsFS.features.length) { textCntl.text += " (" + formatDistance(feature.attributes.length, "miles"); var time:String = formatTime(feature.attributes.time); if (time != "") { textCntl.text += ", " + time; } textCntl.text += ")"; } textCntl.addEventListener(MouseEvent.CLICK, directionsSegmentClickHandler, false, 0, true); theDirections.addChild(textCntl); i++; } theDirections.toolTip = "Click individual segment to zoom to that segment."; theSummary.toolTip = "Click to zoom to full route"; theRouteName.toolTip = "Click to zoom to full route"; zoomToFullRoute(); coorComTimer.stop(); coorComTimer.removeEventListener(TimerEvent.TIMER, coorCompare); map.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler); map.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler); } private function solveCompleteHandler(event:RouteEvent):void { var routeResult:RouteResult = event.routeSolveResult.routeResults[0]; directionsFS = routeResult.directions; routeResult.route.symbol = routeSymbol; graphicsLayer.remove(lastRoute); lastRoute = routeResult.route; //snap the route when the mouse over the route lastRoute.addEventListener(MouseEvent.MOUSE_OVER, routeMouseOverHandler); lastRoute.toolTip = routeResult.routeName; if (routeResult.stops && routeResult.stops.length > 0) { lastRoute.toolTip += " with " + routeResult.stops.length + "stops"; } if (routeResult.route.attributes.Total_Time) { lastRoute.toolTip += " in " + Math.round(Number(routeResult.route.attributes.Total_Time)) + " minutes."; } graphicsLayer.add(lastRoute); } private function faultHandler(event:FaultEvent):void { Alert.show(event.fault.faultString, "Routing Error"); // remove the last stop graphicsLayer.remove(stops.features.pop()); } private function zoomToFullRoute():void { if (segmentGraphic) { graphicsLayer.remove(segmentGraphic); segmentGraphic = null; } map.extent = directionsFS.extent; if (!map.extent.containsExtent(directionsFS.extent)) { map.level--; // make sure the whole extent is visible } } private function formatDistance(dist:Number, units:String):String { var result:String = ""; var d:Number = Math.round(dist * 100) / 100; if (d != 0) { result = d + " " + units; } return result; } private function formatTime(time:Number):String { var result:String; var hr:Number = Math.floor(time / 60); var min:Number = Math.round(time % 60); if (hr < 1 && min < 1) { result = ""; } else if (hr < 1 && min < 2) { result = min + " minute"; } else if (hr < 1) { result = min + " minutes"; } else { result = hr + " hour(s) " + min + " minute(s)"; } return result; } private function directionsSegmentClickHandler(event:MouseEvent):void { var textCntl:Text = event.currentTarget as Text; var segment:Graphic = directionsFS.features[parseInt(textCntl.text) - 1]; map.extent = segment.geometry.extent; if (!map.extent.containsExtent(segment.geometry.extent)) { map.level--; // make sure the whole extent is visible } if (!segmentGraphic) { segmentGraphic = new Graphic(segment.geometry, segmentSymbol); graphicsLayer.add(segmentGraphic); } else { segmentGraphic.geometry = segment.geometry; } } ]]> </mx:Script> <!-- start declarations --> <esri:RouteTask id="routeTask" concurrency="last" fault="faultHandler(event)" solveComplete="solveCompleteHandler(event)" url="http://tasks.arcgisonline.com/ArcGIS/rest/services/NetworkAnalysis/ESRI_Route_NA/NAServer/Route" /> <esri:RouteParameters id="routeParams" findBestSequence="true" preserveFirstStop="true" preserveLastStop="true" stops="{stops}" returnDirections="true"/> <esri:SimpleMarkerSymbol id="stopSymbol" size="15" style="triangle"> <esri:SimpleLineSymbol width="4"/> </esri:SimpleMarkerSymbol> <esri:SimpleMarkerSymbol id="routeOverSymbol" size="10" style="circle" color="0xFFFFFF" alpha="0.7"> <esri:SimpleLineSymbol width="2"/> </esri:SimpleMarkerSymbol> <esri:SimpleLineSymbol id="routeSymbol" color="0x0000FF" alpha="0.3" width="5"/> <esri:SimpleLineSymbol id="routeMouseOverSymbol" color="0x0000FF" alpha="0.7" width="6"/> <esri:SimpleLineSymbol id="segmentSymbol" color="0xFF0000" alpha="0.5" width="8"/> <!-- end declarations --> <mx:HBox width="100%" height="100%"> <esri:Map id="map" mapClick="mapClickHandler(event)" mouseDown="mouseDownHandler(event)"> <esri:extent> <esri:Extent xmin="-117.22" ymin="34.04" xmax="-117.17" ymax="34.07"> <esri:SpatialReference wkid="4326"/> </esri:Extent> </esri:extent> <esri:ArcGISTiledMapServiceLayer url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/> <esri:GraphicsLayer id="graphicsLayer"/> <esri:GraphicsLayer id="routeOverGraphicLayer"/> </esri:Map> <mx:VBox width="200" height="100%" backgroundColor="white"> <mx:Text id="theRouteName" click="zoomToFullRoute()" fontWeight="bold" text="{directionsFS.routeName}" toolTip="Click to zoom to full route" width="100%"/> <mx:Text id="theSummary" click="zoomToFullRoute()" text="Total Distance: {formatDistance(directionsFS.totalLength, 'miles')}{NL}Total Time: {formatTime(directionsFS.totalTime)}" width="100%"/> <mx:HRule width="100%"/> <mx:VBox id="theDirections" width="100%" height="100%" minHeight="0"> <mx:Label text="Click 'Get Directions' above to display driving directions here..."/> </mx:VBox> </mx:VBox> </mx:HBox> </mx:Application>
相关文章推荐
- 路径分析,可以拖动上面的节点,动态修改
- 路径分析,可以拖动上面的节点,动态修改(转帖自heyubingzju)
- 动态修改SiteMapPath - 代码生成所有节点 实例
- dom节点操作,画图分析,方法说明,你在这里可以看到别人看不到的
- Flume NG源码分析(二)支持运行时动态修改配置的配置模块
- 可以修改代码世界中一类事物的属性、方法,这是动态语言超越静态语言之处
- 高仿新浪点击图片放大(可以拖动,动态缩小放大,以及再次点击图片消失和保存图片的功能)
- Java-马士兵设计模式学习笔记-代理模式--动态代理 修改成可以代理任意接口
- 动态修改CDockablePane上面的工具条CMFCToolBar的信息提示(续1)
- 动态修改DOM 里面的 id 属性的弊端分析
- java的小说展示,下载在查看所有(文件路径找不到,可以修改)
- 关于ClickOnce的问答:请问ClickOnce的客户端安装路径可以修改吗?
- 终于找到一个方法可以使用EF的时候动态指定数据库路径了
- AsyncTask为什么可以在回调中修改UI(源码分析)
- 怎样动态修改CDockablePane上面的工具条CMFCToolBar的信息提示和prompt
- 找出二叉树中和最大的路径,路径可以从任意节点开始,到任意节点结束。
- JS - [IE,FF]动态获取节点代码innerHTML分析
- Flex中如何通过dragEnabled, dropEnabled和dragMoveEnabled属性,使Tree中的节点可以被拖动重新排序
- 使用 Rad Controls 实现 可拖动节点 Tree (源代码可以下载了)
- 动态修改CDockablePane上面的工具条CMFCToolBar的信息提示(续2)