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

猜你喜欢

转载自lgn395wp.iteye.com/blog/1359543
今日推荐