要求:仪器采集了风场的数据,数据包括:经度、纬度、风速、风向等信息。要求将采集到的风场信息在地图上展示,风力的等级按表1进行划分,在地图上使用图2的方式进行显示,风向以正北为0度顺时针方向递增。
/** * WindMarkerSymbol.as * 风场样式实现类 * @kongj18 **/ package com.kongj18.symbol { import com.esri.ags.Map; import com.esri.ags.geometry.Geometry; import com.esri.ags.geometry.MapPoint; import com.esri.ags.geometry.Multipoint; import com.esri.ags.symbols.Symbol; import flash.display.Graphics; import flash.display.Sprite; public class WindMarkerSymbol extends Symbol { private var _power:Number = 0; private var _anlge:Number = 0; private var _color:uint = 0xFF0000; private var _alpha:Number = 1; private var _angleBArray:Array = [Math.atan(4.0 / 10), Math.atan(8.0 / 10), Math.atan(4.0 / 7), Math.atan(8.0 / 7), Math.atan(4.0 / 4), Math.atan(8.0 / 4), Math.atan(8.0 / 1)]; private var _triangleHypotenuses:Array = [Math.sqrt(4 * 4 + 10 * 10), Math.sqrt(8 * 8 + 10 * 10), Math.sqrt(4 * 4 + 7 * 7), Math.sqrt(8 * 8 + 7 * 7), Math.sqrt(4 * 4 + 4 * 4), Math.sqrt(8 * 8 + 4 * 4), Math.sqrt(8 * 8 + 1 * 1)]; /** * 构造一个风场样式对象 * @param power 风力 * @param angle 角度 * @param color 颜色 * @param alpha 透明度 **/ public function WindMarkerSymbol(power:Number=0,angle:Number=0,color:uint=0xFF0000,alpha:Number=1) { this.power = power; this.anlge = angle; this.color = color; this.alpha = alpha; } public static function getWindMarkerSymbolByspeed(speed:Number=0,angle:Number=0,color:uint=0xFF0000,alpha:Number=1):WindMarkerSymbol { var power:Number = 0; if (speed <= 0.2) { power = 0; } else if (speed >= 0.3 && speed <= 1.5) { power = 1; } else if (speed >= 1.6 && speed <= 3.3) { power = 2; } else if (speed >= 3.4 && speed <= 5.4) { power = 3; } else if (speed >= 5.5 && speed <= 7.9) { power = 4; } else if (speed >= 8.0 && speed <= 10.7) { power = 5; } else if (speed >= 10.8 && speed <= 13.8) { power = 6; } else if (speed >= 13.9 && speed <= 17.1) { power = 7; } else if (speed >= 17.2 && speed <= 20.7) { power = 8; } else if (speed >= 20.8 && speed <= 24.4) { power = 9; } else if (speed >= 24.5 && speed <= 28.4) { power = 10; } else if (speed >= 28.5 && speed <= 32.6) { power = 11; } else if (speed > 32.7) { power = 12; } return new WindMarkerSymbol(power, angle, color, alpha); } public function get alpha():Number { return _alpha; } public function set alpha(value:Number):void { _alpha = value; } public function get color():uint { return _color; } public function set color(value:uint):void { _color = value; } public function get anlge():Number { return _anlge; } public function set anlge(value:Number):void { _anlge = value; } public function get power():Number { return _power; } public function set power(value:Number):void { _power = Math.floor(value); } override public function clear(sprite:Sprite):void { sprite.graphics.clear(); sprite.x = 0; sprite.y = 0; } override public function destroy(sprite:Sprite):void { sprite.graphics.clear(); } override public function draw(sprite:Sprite, geometry:Geometry, attributes:Object, map:Map):void { var geometries:Vector.<Geometry> = getWrapAroundGeometries(map, geometry); if (geometry) { for each (var geom:Geometry in geometries) { if (geom.type == Geometry.MAPPOINT) { drawPoint(sprite.graphics, geom as MapPoint, map); } else if (geom.type == Geometry.MULTIPOINT) { for each (var point:MapPoint in(geom as Multipoint).points) { drawPoint(sprite.graphics, point, map); } } } } } /** * 绘制图标 **/ private function drawPoint(g:Graphics, mapPoint:MapPoint, map:Map):void { var sx:Number = toScreenX(map, mapPoint.x); var sy:Number = toScreenY(map, mapPoint.y); var halfLength:Number = 10; var dx:Number = halfLength * Math.sin(this.anlge * Math.PI / 180); var dy:Number = halfLength * Math.cos(this.anlge * Math.PI / 180); var halfDx:Number = 7 * Math.sin(this.anlge * Math.PI / 180); var halfDy:Number = 7 * Math.cos(this.anlge * Math.PI / 180); g.lineStyle(2, this.color); if (power <= 0) { g.drawCircle(sx, sy, 2); } else { g.moveTo(sx + dx, sy - dy); g.lineTo(sx - halfDx, sy + halfDy); } if (this.power > 0 && power < 8) { for (var i:Number=0; i<power; i++) { if (i % 2 != 0 || i == power -1) { var triangleDxL:Number = (10 - Math.floor(i / 2) * 3) * Math.sin(this.anlge * Math.PI / 180); var triangleDyL:Number = (10 - Math.floor(i / 2) * 3) * Math.cos(this.anlge * Math.PI / 180); if (i == 6) { triangleDxL = (10 - 9) * Math.sin(this.anlge * Math.PI / 180); triangleDyL = (10 - 9) * Math.cos(this.anlge * Math.PI / 180); } var triangleDxR:Number = _triangleHypotenuses[i] * Math.sin(_angleBArray[i] + this.anlge * Math.PI / 180); var triangleDyR:Number = _triangleHypotenuses[i] * Math.cos(_angleBArray[i] + this.anlge * Math.PI / 180); g.moveTo(sx + triangleDxL, sy - triangleDyL); g.lineTo(sx + triangleDxR, sy - triangleDyR); } } } else if (power >= 8) { var triangleDxL:Number = (10 - 6) * Math.sin(this.anlge * Math.PI / 180); var triangleDyL:Number = (10 - 6) * Math.cos(this.anlge * Math.PI / 180); var triangleDxR:Number = _triangleHypotenuses[1] * Math.sin(_angleBArray[1] + this.anlge * Math.PI / 180); var triangleDyR:Number = _triangleHypotenuses[1] * Math.cos(_angleBArray[1] + this.anlge * Math.PI / 180); g.moveTo(sx + dx, sy - dy); g.lineTo(sx + triangleDxR, sy - triangleDyR); g.lineTo(sx + triangleDxL, sy - triangleDyL); } } } }
/** * Projection.as * 经纬度与墨卡托投影互转,精度要求不高的时候可以用 * @kongj18 **/ package com.kongj18.util { public class Projection { public function Projection() { } /** 把经度转化成墨卡托投影 */ public static function projectLon(x:Number):Number { return x*20037508.34/180; } /** 把纬度转化成墨卡托投影 */ public static function projectLat(y:Number):Number { return Math.log(Math.tan((90+y)*Math.PI/360))/(Math.PI/180)*20037508.34/180; } /** 把墨卡托投影的x转化成经度 */ public static function projectX(x:Number):Number { return x/20037508.34*180; } /** 把墨卡托投影的Y转换成纬度 */ public static function projectY(y:Number):Number { y = y/20037508.34*180; return 180/Math.PI*(2*Math.atan(Math.exp(y*Math.PI/180))-Math.PI/2); } } }
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx= xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" xmlns:esri=> <fx:Script> <![CDATA[ import com.esri.ags.Graphic; import com.esri.ags.events.ExtentEvent; import com.esri.ags.events.MapEvent; import com.esri.ags.geometry.MapPoint; import com.kongj18.symbol.WindMarkerSymbol; import com.kongj18.util.Projection; protected function mapLoadHandler(event:MapEvent):void { for (var i:Number=0; i<50; i++) { for (var j:Number=0; j<50; j++) { var point:MapPoint = new MapPoint(Projection.projectLon(117.9 + j * 0.01), Projection.projectLat(24.3 + i * 0.01)); var speed:Number = Math.random() * 33; var angle:Number = Math.random() * 360; var symbol:WindMarkerSymbol = WindMarkerSymbol.getWindMarkerSymbolByspeed(speed, angle); var graphic:Graphic = new Graphic(point, symbol); gLayer.add(graphic); } } } ]]> </fx:Script> <fx:Declarations> <!-- 将非可视元素(例如服务、值对象)放在此处 --> </fx:Declarations> <esri:Map load="mapLoadHandler(event)"> <esri:extent> <esri:Extent xmin="13124144.503386792" ymin="2800475.457445229" xmax="13176350.993705496" ymax="2826196.5174631556"> <esri:SpatialReference wkid="102100"/> </esri:Extent> </esri:extent> <esri:ArcGISTiledMapServiceLayer url="http://cache1.arcgisonline.cn/arcgis/rest/services/ChinaOnlineCommunity/MapServer"/> <esri:GraphicsLayer id="gLayer"/> </esri:Map> </s:Application>
测试结果:
参考资料:https://developers.arcgis.com/flex/sample-code/custom-symbol.htm
Demo下载地址:http://download.csdn.net/detail/q1466136480/7975393