Arcgis Flex Api自定义点样式实现风场显示

要求:仪器采集了风场的数据,数据包括:经度、纬度、风速、风向等信息。要求将采集到的风场信息在地图上展示,风力的等级按表1进行划分,在地图上使用图2的方式进行显示,风向以正北为0度顺时针方向递增。

Arcgis Flex Api自定义点样式实现风场显示

Arcgis Flex Api自定义点样式实现风场显示

/**
 * 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>

测试结果:

Arcgis Flex Api自定义点样式实现风场显示

参考资料:https://developers.arcgis.com/flex/sample-code/custom-symbol.htm

Demo下载地址:http://download.csdn.net/detail/q1466136480/7975393

你可能感兴趣的:(Flex,arcgis,风场)