PageRenderTime 23ms CodeModel.GetById 12ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/src/com/google/maps/extras/arcgislink/ArcGISTileLayer.as

http://gmaps-utility-library-flash.googlecode.com/
ActionScript | 217 lines | 143 code | 31 blank | 43 comment | 20 complexity | dc3eb8c983c1bc8069f0f199f9950bbe MD5 | raw file
  1/*
  2 * ArcGIS for Google Maps Flash API
  3 *
  4 * License http://www.apache.org/licenses/LICENSE-2.0
  5 */
  6 /**
  7 * @author nianwei at gmail dot com
  8 */ 
  9
 10package com.google.maps.extras.arcgislink {
 11  import com.google.maps.*;
 12  import com.google.maps.interfaces.*;
 13
 14  import flash.display.DisplayObject;
 15  import flash.display.Loader;
 16  import flash.events.*;
 17  import flash.geom.Point;
 18  import flash.net.URLRequest;
 19   import com.google.maps.extras.arcgislink.*;
 20 import com.google.maps.extras.arcgislink.*;
 21  /**
 22   * Used for cached map service
 23   */
 24  //There some unique challenges in AS3 compare to JS in implementing this class :
 25  // --can not call super in a callback function, must be inside the constructor context
 26  //--copyright et once passed in constructor the overriden functions such as getCopyrightCollection etc does not seem to be used.
 27  public class ArcGISTileLayer extends TileLayerBase implements IEventDispatcher {
 28
 29    private var baseUrl_:String;
 30    private var mapService_:MapService;
 31    private var urlTemplate_:String;
 32    private var numOfHosts_:int;
 33    internal var projection_:ArcGISTileConfig; // need access from MapType
 34    private var fullBounds_:* /*Envelope*/ ;
 35    private var initialBounds_:* /*Envelope*/ ;
 36
 37    public function ArcGISTileLayer(service:*, opt_layerOpts:ArcGISTileLayerOptions=undefined) {
 38      dispatcher_=new EventDispatcher(this);
 39      opt_layerOpts=opt_layerOpts || new ArcGISTileLayerOptions({});
 40      this.mapService_=(service is MapService) ? service as MapService : new MapService(service as String);
 41      if (opt_layerOpts.name) {
 42        this.mapService_.name=opt_layerOpts.name;
 43      }
 44      this.alpha_=isNaN(opt_layerOpts.alpha) ? Alpha.OPAQUE : opt_layerOpts.alpha;
 45
 46      //In the format of mt[number].domain.com
 47      if (opt_layerOpts.hosts) {
 48        var pro:String=ArcGISUtil.extractString(this.mapService_.url, '', '://');
 49        var host:String=ArcGISUtil.extractString(this.mapService_.url, '://', '/');
 50        var path:String=ArcGISUtil.extractString(this.mapService_.url, pro + '://' + host, '');
 51        this.urlTemplate_=pro + '://' + opt_layerOpts.hosts + path;
 52        this.numOfHosts_=parseInt(ArcGISUtil.extractString(opt_layerOpts.hosts, '[', ']'), 10);
 53      }
 54      var copy:ICopyrightCollection=opt_layerOpts.copyrights;
 55      if (!copy) {
 56        copy=new CopyrightCollection('pre');
 57        copy.addCopyright(new Copyright('1', new LatLngBounds(new LatLng(-90, -180), new LatLng(90, 180)), 0, ''));
 58      }
 59      this.copy_=copy;
 60      this.minZoom_=opt_layerOpts.minResolution || 0;
 61      this.maxZoom_=opt_layerOpts.maxResolution || 20;
 62
 63      if (this.mapService_.hasLoaded()) {
 64        this.init_(opt_layerOpts);
 65      } else {
 66        var me:ArcGISTileLayer=this;
 67        this.mapService_.addEventListener(ServiceEvent.LOAD, function():void {
 68            me.init_(opt_layerOpts);
 69            me.dispatchEvent(new ServiceEvent(ServiceEvent.LOAD));
 70          });
 71      }
 72      super(this.copy_, this.minZoom_, this.maxZoom_, this.alpha_);
 73      if (this.mapService_.hasLoaded()) {
 74        dispatchEvent(new ServiceEvent(ServiceEvent.LOAD));
 75      }
 76    }
 77
 78    /**
 79     * Initialize the tile layer from a loaded map service
 80     * @param {ArcGISMapService} mapService
 81     * @param {Object} opt_layerOpts
 82     */
 83    private function init_(opt_layerOpts:*):void {
 84      this.projection_=new ArcGISTileConfig(this.mapService_.tileInfo, this.mapService_.fullExtent);
 85      var copy:CopyrightCollection=opt_layerOpts.copyrights;
 86      if (!copy) {
 87        copy=new CopyrightCollection('');
 88        copy.addCopyright(new Copyright('1', ArcGISUtil.fromEnvelopeToLatLngBounds(this.mapService_.fullExtent), this.projection_.zoomOffset_, this.mapService_.copyrightText));
 89      }
 90      this.copy_=copy;
 91      this.minZoom_=opt_layerOpts.minResolution || this.projection_.minResolution();
 92      this.maxZoom_=opt_layerOpts.maxResolution || this.projection_.maxResolution();
 93      // It seems unlike in JS, AS3's super can be called only in one place in constructor, 
 94      // as a workaround all get methods are overriden.
 95      // TileLayerBase.call(this, copy, minZoom, maxZoom, opt_layerOpts);
 96      // super(copy, minZoom, maxZoom, opt_layerOpts.alpha);
 97    }
 98    
 99
100    /**
101     * Creates and loads a tile (x, y) at the given zoom level.
102     * @param tilePos  Tile coordinates.
103     * @param zoom  Tile zoom.
104     * @return  Display object representing the tile.
105     */
106    public override function loadTile(tile:Point, zoom:Number):DisplayObject {
107      var url:String; //.minResolution()
108      var z:Number=zoom - (this.projection_ ? this.projection_.zoomOffset_ : this.getMinResolution()); //.minResolution());
109      if (!isNaN(tile.x) && !isNaN(tile.y) && z >= 0) {
110        var u:String=this.mapService_.url;
111        if (this.urlTemplate_) {
112          u=this.urlTemplate_.replace('[' + this.numOfHosts_ + ']', '' + ((tile.y + tile.x) % this.numOfHosts_));
113        }
114        url=u + '/tile/' + z + '/' + tile.y + '/' + tile.x;
115
116      }
117      var loader:Loader=new Loader();
118      if (url!=null){
119        loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
120        loader.load(new URLRequest(url));
121      }
122      return loader;
123    }
124
125    private function ioErrorHandler(event:IOErrorEvent):void {
126      trace("ioErrorHandler: " + event);
127    }
128
129    /**
130     * Gain access to the underline {@link ArcGISMapService}
131     * @return {MapSerive}
132     */
133    public function getMapService():MapService {
134      return this.mapService_;
135    }
136
137    /**
138     * Get full bounds of the to the underline {@link ArcGISMapService}
139     * @return {GLatLngBounds}
140     */
141    public function getFullBounds():LatLngBounds {
142      this.fullBounds_=this.fullBounds_ || ArcGISUtil.fromEnvelopeToLatLngBounds(this.mapService_.fullExtent);
143      return this.fullBounds_;
144    }
145
146    public function getInitialBounds():LatLngBounds {
147      this.initialBounds_=this.initialBounds_ || ArcGISUtil.fromEnvelopeToLatLngBounds(this.mapService_.initialExtent);
148      return this.initialBounds_;
149    }
150
151    /**
152     * Returns the {@link ArcGISProjection}, a subclass of <code>GProjection</code>
153     *  used by this ArcGISTileLayer.
154     * @return {ArcGISProjection}
155     */
156    public function getProjection():ArcGISTileConfig {
157      return this.projection_ || ArcGISTileConfig.GOOGLE_MAPS;
158    }
159
160    public function hasLoaded():Boolean {
161      return this.mapService_.hasLoaded();
162    }
163
164    public function getName():String {
165      return this.mapService_.name;
166    }
167    private var dispatcher_:EventDispatcher;
168
169    public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void {
170
171      dispatcher_.addEventListener(type, listener, useCapture, priority);
172    }
173
174    public function dispatchEvent(evt:Event):Boolean {
175      return dispatcher_.dispatchEvent(evt);
176    }
177
178    public function hasEventListener(type:String):Boolean {
179      return dispatcher_.hasEventListener(type);
180    }
181
182    public function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void {
183      dispatcher_.removeEventListener(type, listener, useCapture);
184    }
185
186    public function willTrigger(type:String):Boolean {
187      return dispatcher_.willTrigger(type);
188    }
189
190
191    private var copy_:ICopyrightCollection;
192
193    public override function getCopyrightCollection():ICopyrightCollection {
194      return this.copy_ ? this.copy_ : super.getCopyrightCollection();
195    }
196    private var maxZoom_:Number;
197
198    public override function getMaxResolution():Number {
199      return this.maxZoom_ ? this.maxZoom_ : super.getMaxResolution();
200    }
201    private var minZoom_:Number;
202
203    public override function getMinResolution():Number {
204      return this.minZoom_ ? this.minZoom_ : super.getMinResolution();
205    }
206    private var alpha_:Number;
207
208    public override function getAlpha():Number {
209      return this.alpha_ ? this.alpha_ : super.getAlpha();
210    }
211
212    public function setAlpha(alpha:Number):void {
213      this.alpha_=alpha;
214    }
215
216  }
217}