Adobe Flash Builder 4.5 Android Air 程序开发系列 之9 定位

Adobe Flash Builder 4.5 Android Air 程序开发系列 之九 定位

Adobe Flash Builder 4.5 Android Air 程序开发系列 之九 定位
2011年09月04日
  地理位置
  地理位置,API能够定位到设备的一些信息。
  地理位置类
  flash.events.GeolocationEvent
  权限:
  
  
  File loaction 是指与GPS的通行,Corase loaction 是指与网络的通信。接下我们将会对这两个概念做详细的介绍。
  在开发或者测试的过程中,设置【设置】|【位置和安全】|使用GPS卫星 和 【设置】|【位置和安全】|【使用无线网络】 都为选
  中状态。
  //判断是否支持定位
  import flash.events.GeolocationEvent;
  if(Geolocation.isSupported)
  //Geolocation.supported
  我们写一个简单的应用程序来监听Geolocation 的事件的更新。设置Geolocation为类的实例变量,不是局部变量,以保证我们在使
  用他的
  时候没有被GC回收。
  import flash.events.GeolocationEvent;
  private var geolocation:Geolocation;
  if(Geolocation.isSupported)
  {
  geolocation=new Geolocation();
  geolocation.addEventListener(GeolocationEvent.UPDATE,onTravel);
  }
  private function onTravel(event:GeolocationEvent):void
  {
  trace(event.latitude)
  trace(event.longitude)
  }
  用户可以设置启用与禁用GPS装置,所以应用程序必须检查muted 属性,在初始化程序的时候需要访问该属性,还有一种情况是
  在程序运行时监听更新的状态。
  import flash.events.StatusEvent;
  if(!geolocation.muted)
  {
  geolocation.addEventListener(StatusEvent.STATUS,onStatusChange);
  }
  else
  {
  //inform the user to turn on the location sensor
  }
  function onStatusChange(event:StatusEvent):void
  {
  trace("status"+event.code)
  if(event.code=="Geolocation.Muted")
  {
  //inform the user to turn on the location sensor
  }
  }
  GeolocationEvent
  GeolocationEvent.UPDATE 事件在第一次创建时就会被触发。如果设备在移动或者其他方式使设备位置发生变化的话,这个事件也
  会被触发。
  这样刷新的频率会比较快,为了保护电池的寿命,可以通过设置setRequestUpdateInterval ,使刷新的频率降低,因为你的应用程
  序本身不需要刷新很快。
  Geolocation.setRequestUpdateInterval(10000);
  event.latitude event.longitude 表示经纬度
  event.horizontalAccuracy event.verticalAccuracy 单位是米
  event.timeStamp 是以毫秒为单位,计算从程序初始化到移动的时间。
  event.altitude 单位是米,event.speed 单位是米/秒
  全球定位系统 和网络
  GPS 或者是WIFI 是否打开
  flash.net.NetworkInfo 类提供了 在电脑以及设备上的网络接口。权限:
  
  
  //检查是否支持
  if(NetworkInfo.isSupported)
  {
  //network information supported
  }
  NetworkInfo 存储了一些网络接口。
  var network:NetwrkInfo=NetworkInfo.networkInfo;
  for each(var object:NetworkInterface in network.findInterfaces())
  {
  trace(object.name);
  }
  方向地理编码
  我们从设备获取的仅仅是经纬度,只有在地图中会比较有用。有一种技术就是反向地理编码,传递过去经纬度,发送过来的是地址
  。
  查看一下的实例:
  权限:
  
  import flash.display.Sprite;
  import flash.display.StageAlign;
  import flash.display.StageScaleMode;
  import flash.events.Event;
  import flash.events.IOErrorEvent;
  import flash.events.GeolocationEvent;
  import flash.events.StatusEvent;
  import flash.net.URLLoader;
  import flash.net.URLRequest;
  import flash.net.URLRequestMethod;
  import flash.net.URLVariables;
  import flash.sensors.Geolocation;
  public class ReverseGeo extends Sprite
  {
  private const YAHOO_URL:String = "http://where.yahooapis.com/geocode";
  private const ID:String = "YOUR_ID";
  private var _geo:Geolocation;
  private var _loader:URLLoader;
  public function ReverseGeo()
  {
  stage.align = StageAlign.TOP_LEFT;
  stage.scaleMode = StageScaleMode.NO_SCALE;
  if (Geolocation.isSupported)
  {
  init();
  }
  }
  private function init():void
  {
  _geo = new Geolocation();
  _geo.addEventListener(GeolocationEvent.UPDATE, onUpdate);
  }
  private function onUpdate(event:GeolocationEvent):void
  {
  var request:URLRequest = new URLRequest(YAHOO_URL);
  var variables:URLVariables = new URLVariables();
  variables.q =     event.latitude.toString() + "\n" + event.longitude.toString();
  variables.gflags = "R";
  variables.appid = ID;
  request.data = variables;
  request.method = URLRequestMethod.GET;
  _loader = new URLLoader();
  _loader.addEventListener(Event.COMPLETE, onLocationLoaded);
  _loader.addEventListener(IOErrorEvent.IO_ERROR, onError);
  _loader.load(request);
  }
  private function onLocationLoaded(event:Event):void
  {
  trace("*** event", event);
  _loader.removeEventListener(Event.COMPLETE, onLocationLoaded);
  _geo.removeEventListener(GeolocationEvent.UPDATE, onUpdate);
  var xml:XML = new XML(event.target.data);
  trace(xml);
  var city:String = xml.Result.city.text();
  var country:String = xml.Result.country.text();
  trace(city, country);
  }
  private function onError(event:IOErrorEvent):void
  {
  trace("*** error", event);
  }
  }
  地图
  提供地图服务的有 Google Maps,Yahoo Maps,Bing Maps 等等。
  加载google 地图:
  
  import flash.events.GeolocationEvent;
  import flash.net.navigateToURL;
  import flash.net.URLRequest;
  import flash.sensors.Geolocation;
  private function onLocationUpdate(event:GeolocationEvent):void
  {
  geolocation.removeEventListener(GeolocationEvent.UPDATE,onLocationUpdate);
  var long:String=event.longitde.toString();
  var lat:String=event.latitude.toString();
  navigateToURL(new URLRequest("http://maps.google.com/?q="+lat+","+long));
  }
  静态地图
  静态地图提供了一种比较好的解决方案。在AIR程序中时比较轻量级的显示地图。他是对一个位置的快照,但是不能平移和缩放,但
  是可以
  根据GPS很快的加载。
  Yahoo 静态地图
  import flash.display.Loader;
  import flash.display.Sprite;
  import flash.display.StageAlign;
  import flash.display.StageScaleMode;
  import flash.events.Event;
  import flash.events.GeolocationEvent;
  import flash.net.URLLoader;
  import flash.net.URLRequest;
  import flash.sensors.Geolocation;
  public class StaticMap extends Sprite
  {
  private const YAHOO_URL:String = "http://local.yahooapis.com/MapsService/V1/mapImage";
  private const ID:String = "YOUR_ID";
  private var _geo:Geolocation;
  public function StaticMap()
  {
  stage.align = StageAlign.TOP_LEFT;
  stage.scaleMode = StageScaleMode.NO_SCALE;
  if (Geolocation.isSupported)
  {
  init();
  }
  }
  private function init():void
  {
  _geo = new Geolocation();
  _geo.addEventListener(GeolocationEvent.UPDATE, onUpdate);
  }
  // get current latitude and longitude
  private function onUpdate(event:GeolocationEvent):void
  {
  trace("travel", event.latitude, event.longitude);
  var request:String = "?appid="
  + ID
  + "&latitude="
  + event.latitude
  + "&longitude="
  + event.longitude
  + "&zoom=1&image_height="
  + stage.stageHeight
  + "&image_width="
  + stage.stageWidth;
  // request a map image for the location
  var urlLoader:URLLoader = new URLLoader();
  urlLoader.addEventListener(Event.COMPLETE, onXMLReceived);
  urlLoader.load(new URLRequest(YAHOO_URL + request));
  }
  // get an XML with path to static map
  private function onXMLReceived(event:Event):void
  {
  event.target.removeEventListener(Event.COMPLETE, onXMLReceived);
  _geo.removeEventListener(GeolocationEvent.UPDATE, onUpdate);
  var xml:XML = XML(event.currentTarget.data);
  trace("xml", xml);
  // load static map
  var loader:Loader = new Loader();
  loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoaded);
  loader.load(new URLRequest(xml));
  }
  // display static map
  private function onImageLoaded(event:Event):void
  {
  event.currentTarget.removeEventListener(Event.COMPLETE, onImageLoaded);
  this.addChild(event.currentTarget.content);
  }
  }
  Google 静态地图
  import flash.display.Loader;
  import flash.display.Sprite;
  import flash.display.StageAlign;
  import flash.display.StageScaleMode;
  import flash.events.Event;
  import flash.events.GeolocationEvent;
  import flash.net.URLLoader;
  import flash.net.URLRequest;
  import flash.sensors.Geolocation;
  public class StaticMapGoogle extends Sprite
  {
  private const GOOGLE_URL:String = "http://maps.google.com/maps/api/staticmap?";
  private var _geo:Geolocation;
  public function StaticMapGoogle()
  {
  stage.align = StageAlign.TOP_LEFT;
  stage.scaleMode = StageScaleMode.NO_SCALE;
  if (Geolocation.isSupported)
  {
  init();
  }
  }
  private function init():void
  {
  _geo = new Geolocation();
  _geo.addEventListener(GeolocationEvent.UPDATE, onUpdate);
  }
  // get current latitude and longitude
  private function onUpdate(event:GeolocationEvent):void
  {
  // Google API limits image size to 640 pixels
  var width:int = Math.min(640, stage.stageWidth);
  var height:int = Math.min(640, stage.stageHeight);
  var request:String =
  "?&markers=size:large|color:blue|label:L|"
  + event.latitude + "," + event.longitude
  + "&zoom=15&size="
  + width
  + "x"
  + height
  + "&maptype=roadmap&mobile=true&sensor=true";
  // display static map
  var loader:Loader = new Loader();
  loader.y = 75;
  addChild(loader);
  loader.load(new URLRequest(GOOGLE_URL + request));
  }
  }
  动态地图:
  Google Maps API
  从google 的网站下载http://code.google.com/intl/zh-CN/apis/maps/documentation/flash/ 包括两个swc
  (map_1_20.swc 和 map_flex_1_20.swc),
  添加swc类库到项目中。
  权限:
  
  创建Map 对象的实例,Map实例需要你注册的时候添加的 APIkey 以及URL,这样你就建立了一个独立的Android 应用程序。
  实例如下:
  import com.google.maps.InfoWindowOptions;
  import com.google.maps.LatLng;
  import com.google.maps.Map;
  import com.google.maps.MapEvent;
  import com.google.maps.MapMouseEvent;
  import com.google.maps.MapType;
  import com.google.maps.controls.ZoomControl;
  import com.google.maps.overlays.Marker;
  import com.google.maps.overlays.MarkerOptions;
  import com.google.maps.styles.FillStyle;
  import flash.display.Sprite;
  import flash.display.StageAlign;
  import flash.display.StageScaleMode;
  import flash.events.GeolocationEvent;
  import flash.geom.Point;
  import flash.sensors.Geolocation;
  public class DynamicMap extends Sprite
  {
  private const KEY:String = "YOUR_KEY";
  private const SITE:String = "YOUR_SITE";
  private var _geo:Geolocation;
  private var _map:Map;
  public function DynamicMap()
  {
  stage.align = StageAlign.TOP_LEFT;
  stage.scaleMode = StageScaleMode.NO_SCALE;
  if (Geolocation.isSupported)
  {
  init();
  }
  }
  private function init():void
  {
  _geo = new Geolocation();
  // prepare Map object
  _map = new Map();
  _map.key = KEY;
  _map.url = SITE;
  _map.sensor = "true";
  _map.setSize(new Point(stage.stageWidth, stage.stageHeight));
  _map.addEventListener(MapEvent.MAP_READY, onMapReady);
  addChild(_map);
  }
  private function onMapReady(event:MapEvent):void
  {
  _geo.addEventListener(GeolocationEvent.UPDATE, onUpdate);
  }
  private function onUpdate(event:GeolocationEvent):void
  {
  _map.setCenter(new LatLng(event.latitude, event.longitude), 18, MapType.NORMAL_MAP_TYPE);
  _map.addControl(new ZoomControl());
  // Add a marker with a FillStyle and information window
  var options:Object = {hasShadow:true, fillStyle: new FillStyle({color:0x0099FF, alpha:0.75}),
  radius:20};
  var marker:Marker = new Marker(new LatLng(event.latitude, event.longitude), new MarkerOptions
  (options));
  marker.addEventListener(MapMouseEvent.CLICK, markerClicked);
  _map.addOverlay(marker);
  }
  private function markerClicked(event:MapMouseEvent):void
  {
  event.currentTarget.openInfoWindow(new InfoWindowOptions({content:"Hello\nAIR World"}));
  }
  }
  Exif 数据 和地图
  import com.google.maps.Map;
  import com.google.maps.MapEvent;
  import com.google.maps.LatLng;
  import com.google.maps.MapType;
  import com.google.maps.overlays.Marker;
  import com.google.maps.overlays.MarkerOptions;
  import flash.display.Sprite;
  import flash.display.StageAlign;
  import flash.display.StageScaleMode;
  import flash.events.Event;
  import flash.events.MediaEvent;
  import flash.geom.Point;
  import flash.media.CameraRoll;
  import flash.net.URLRequest;
  import jp.shichiseki.exif.ExifInfo;
  import jp.shichiseki.exif.ExifLoader;
  import jp.shichiseki.exif.IFD;
  public class ExifMap extends Sprite
  {
  public const KEY:String = "YOUR_KEY";
  public const SITE:String = "YOUR_SITE";
  private var _cameraRoll:CameraRoll;
  private var _map:Map;
  private var _exifLoader:ExifLoader;
  public function ExifMap()
  {
  stage.align = StageAlign.TOP_LEFT;
  stage.scaleMode = StageScaleMode.NO_SCALE;
  if (CameraRoll.supportsBrowseForImage)
  {
  init();
  }
  }
  private function init():void
  {
  _map = new Map();
  _map.url = SITE;
  _map.key = KEY;
  _map.sensor = "false";
  _map.setSize(new Point(stage.stageWidth, stage.stageHeight));
  _map.addEventListener(MapEvent.MAP_READY, onMapReady);
  addChild(_map);
  }
  private function onMapReady(event:MapEvent):void
  {
  _map.setCenter(new LatLng(40.736072, -73.992062), 14, MapType.NORMAL_MAP_TYPE);
  var camera:CameraRoll = new CameraRoll();
  camera.addEventListener(MediaEvent.SELECT, onImageSelected);
  camera.browseForImage();
  }
  private function onImageSelected(event:MediaEvent):void
  {
  _exifLoader = new ExifLoader();
  _exifLoader.addEventListener(Event.COMPLETE, onImageLoaded);
  _exifLoader.load(new URLRequest(event.data.file.url));
  }
  private function onImageLoaded(event:Event):void
  {
  var exif:ExifInfo = _exifLoader.exif;
  if (exif.ifds.gps["GPSLatitude"] != null)
  {
  var gpsIfd:IFD = exif.ifds.gps;
  var exifLat:Array = gpsIfd["GPSLatitude"] as Array;
  var exifLon:Array = gpsIfd["GPSLongitude"] as Array;
  var latitude:Number = shorten(exifLat, gpsIfd["GPSLatitudeRef"]);
  var longitude:Number = shorten(exifLon, gpsIfd["GPSLongitudeRef"]);
  var marker:Marker = new Marker(new LatLng(latitude, longitude));
  _map.addOverlay(marker);
  _map.setCenter(new LatLng(latitude, longitude));
  } else {
  trace("no gps info");
  }
  }
  private function shorten(info:Array, reference:String):Number
  {
  var degree:Number = info[0] + (info[1]/60) + (info[2]/3600);
  // position from Greenwich and equator
  if (reference == "S" || reference == "W")
  {
  degree *= -1;
  }
  return degree;
  }
  }
  速度
  结论
  分类: Flex