arcgis api for Flex画贝赛尔曲线

来源:互联网 发布:域名怎样防qq管家拦截 编辑:程序博客网 时间:2024/04/28 14:04

         最近在研究用arcgis api for Flex客户端动态画曲线的问题。虽然花了不少时间,最终等值线还是没有预期效果那样画在地图之上,但还是有不少收获。画等值线过程中,需要利用贝赛尔曲线函数来画平滑曲线。网上找了很多资料,都是在用flash环境中的curveTo()方法来画,但是好像这样画出来的曲线是不能在gis图层中显示的,即只能在flash.display.Graphics下的graphics才能使用这个方法,ags中的graphics是不是使用这个方法的。要么本人还没有找到转换方法,要么就根本不能用在gis图层。在网上找到了一篇关于在ags图层中画军标的文章,从这篇文件中得到启示。

先看效果 :



<?xml version="1.0" encoding="utf-8"?><s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"    xmlns:s="library://ns.adobe.com/flex/spark"    xmlns:mx="library://ns.adobe.com/flex/mx"    minWidth="955" minHeight="600" creationComplete="init()"    xmlns:esri="http://www.esri.com/2008/ags"><fx:Declarations><!-- 将非可视元素(例如服务、值对象)放在此处 --></fx:Declarations>    <fx:Script><![CDATA[import com.esri.ags.Graphic;import com.esri.ags.SpatialReference;import com.esri.ags.geometry.MapPoint;import com.esri.ags.geometry.Polyline;import com.esri.ags.layers.GraphicsLayer;private var m_firstpoints:Array;private var graphicsLayer:GraphicsLayer;private var full_polyline:Graphic;private function init():void{map.addEventListener(MouseEvent.CLICK,map_mouseClickHandler);map.addEventListener(MouseEvent.DOUBLE_CLICK,map_mouseDoubleClickHandler);graphicsLayer=new GraphicsLayer();map.addLayer(graphicsLayer);}public function map_mouseClickHandler(event:MouseEvent):void{map.mapNavigationEnabled=false;//确定点击的地图点的坐标,然后放到数组中var m_point:MapPoint=map.toMapFromStage(event.stageX, event.stageY);if (m_firstpoints == null){m_firstpoints=new Array();}m_firstpoints.push(m_point);}public function map_mouseDoubleClickHandler(event:MouseEvent):void{var pg:Polyline=drawLine(m_firstpoints,100);full_polyline=new Graphic(pg);graphicsLayer.add(full_polyline);}private function drawLine(inputPoints:Array,mapWidth:Number):Polyline{var points:Array=new Array();for(var k:int=0;k<inputPoints.length;k++){points.push(inputPoints[k]);if(k>0&&k<inputPoints.length-2){var p:MapPoint=new MapPoint((inputPoints[k].x+inputPoints[k+1].x)/2,(inputPoints[k].y+inputPoints[k+1].y)/2,new SpatialReference(4326));points.push(p);}}var curvepoints:Array=getzz_geometry(points,20);var dgbj_geometry:Array=getdbx_geometry(curvepoints,mapWidth,20);var full_gbjpolyline:Polyline=new Polyline(dgbj_geometry);return full_gbjpolyline;}/* 求中轴线上所有的点 */private function getzz_geometry(inputPoints:Array,bzt:Number):Array{//首先定义中轴曲线的点坐标var curvepoints:Array=new Array();var i:int;var j:Number;var pos_x:Number;var pos_y:Number;var m_point:MapPoint;for ( i=0; i < inputPoints.length-2; i=i + 2){for (j=0; j <= 1+0.00001; j=j + 1/bzt){if (i != 0 && j == 0)continue;pos_x=Math.pow((1 - j), 2) * inputPoints[i].x + 2 * j * (1 - j) * inputPoints[i + 1].x + Math.pow(j, 2) * inputPoints[i + 2].x;pos_y=Math.pow((1 - j), 2) * inputPoints[i].y + 2 * j * (1 - j) * inputPoints[i + 1].y + Math.pow(j, 2) * inputPoints[i + 2].y;m_point=new MapPoint(pos_x, pos_y);//中轴线的点数curvepoints.push(m_point);}}return curvepoints;}/* 获得曲线点组 */private function getdbx_geometry(curvepoints:Array,mapWidth:Number,bzt:Number):Array{var bottomcurepoints:Array=new Array();var c_length:Number=curvepoints.length;var dis:Number= mapWidth/20.0;var pos_x:Number;var pos_y:Number;var pre_pos_x:Number;var pre_pos_y:Number;var bb:Number;var slope:Number;var cos_number:Number;var sin_number:Number;var pre_point:MapPoint;var m_point:MapPoint;for (var u:Number=0; u < curvepoints.length; u++){if (u == 0){continue;}else{var bottom_pos_x:Number;var bottom_pos_y:Number;m_point=curvepoints[u];pos_x=m_point.x;pos_y=m_point.y;pre_point=curvepoints[u - 1];pre_pos_x=pre_point.x;pre_pos_y=pre_point.y;slope=(pos_y - pre_pos_y) / (pos_x - pre_pos_x);bb=dis * (1 - u / c_length * 0.9);cos_number=Math.cos(Math.atan(slope) - Math.PI / 2);sin_number=Math.sin(Math.atan(slope) - Math.PI / 2);if (pre_pos_x <= pos_x && pre_pos_y <= pos_y){bottom_pos_x=pre_pos_x + ((bb * cos_number) < 0 ? (-bb * cos_number) : (bb * cos_number));bottom_pos_y=pre_pos_y - ((bb * sin_number) < 0 ? (-bb * sin_number) : (bb * sin_number));}else if (pre_pos_x <= pos_x && pre_pos_y > pos_y){bottom_pos_x=pre_pos_x - ((bb * cos_number) < 0 ? (-bb * cos_number) : (bb * cos_number));bottom_pos_y=pre_pos_y - ((bb * sin_number) < 0 ? (-bb * sin_number) : (bb * sin_number));}else if (pre_pos_x >= pos_x && pre_pos_y >= pos_y){bottom_pos_x=pre_pos_x - ((bb * cos_number) < 0 ? (-bb * cos_number) : (bb * cos_number));bottom_pos_y=pre_pos_y + ((bb * sin_number) < 0 ? (-bb * sin_number) : (bb * sin_number));}else if (pre_pos_x >= pos_x && pre_pos_y <= pos_y){bottom_pos_x=pre_pos_x + ((bb * cos_number) < 0 ? (-bb * cos_number) : (bb * cos_number));bottom_pos_y=pre_pos_y + ((bb * sin_number) < 0 ? (-bb * sin_number) : (bb * sin_number));}var bottom_point:MapPoint=new MapPoint(bottom_pos_x, bottom_pos_y);bottomcurepoints.push(bottom_point);}}var rings:Array=new Array();rings.push(bottomcurepoints);return rings;}]]></fx:Script><s:BorderContainer width="100%" height="100%"><esri:Map id="map"><esri:ArcGISTiledMapServiceLayer id="layer" url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/></esri:Map></s:BorderContainer></s:Application>
这样就可以画出一条平滑的贝赛尔曲线了。这是直接利用贝赛尔曲线公式,而没有利用flash.display.Graphics.curveTo()方法,虽然简单了点,但效果还不错。


原创粉丝点击