PageRenderTime 36ms CodeModel.GetById 17ms app.highlight 14ms RepoModel.GetById 1ms app.codeStats 0ms

/src/com/google/maps/extras/markerclusterer/ClusterMarker.as

http://gmaps-utility-library-flash.googlecode.com/
ActionScript | 241 lines | 100 code | 35 blank | 106 comment | 4 complexity | 82c2ce9167a2e042dc39ff5d7336ce43 MD5 | raw file
  1/**
  2 * @name MarkerClusterer for Flash
  3 * @version 1.0
  4 * @author Xiaoxi Wu
  5 * @copyright (c) 2009 Xiaoxi Wu
  6 * @fileoverview
  7 * Ported from Javascript to Actionscript 3 by Sean Toru
  8 * Ported for use in Flex (removal of fl. libraries) by Ian Watkins
  9 * Reflectored for both Flash and Flex, 
 10 * and maintained by Juguang XIAO (juguang@gmail.com)
 11 * 
 12 * This actionscript library creates and manages per-zoom-level 
 13 * clusters for large amounts of markers (hundreds or thousands).
 14 * This library was inspired by the <a href="http://www.maptimize.com">
 15 * Maptimize</a> hosted clustering solution.
 16 * <br /><br/>
 17 * <b>How it works</b>:<br/>
 18 * The <code>MarkerClusterer</code> will group markers into clusters according to
 19 * their distance from a cluster's center. When a marker is added,
 20 * the marker cluster will find a position in all the clusters, and 
 21 * if it fails to find one, it will create a new cluster with the marker.
 22 * The number of markers in a cluster will be displayed
 23 * on the cluster marker. When the map viewport changes,
 24 * <code>MarkerClusterer</code> will destroy the clusters in the viewport 
 25 * and regroup them into new clusters.
 26 *
 27 */
 28
 29/*
 30 * Licensed under the Apache License, Version 2.0 (the "License");
 31 * you may not use this file except in compliance with the License.
 32 * You may obtain a copy of the License at
 33 *
 34 *     http://www.apache.org/licenses/LICENSE-2.0
 35 *
 36 * Unless required by applicable law or agreed to in writing, software
 37 * distributed under the License is distributed on an "AS IS" BASIS,
 38 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 39 * See the License for the specific language governing permissions and
 40 * limitations under the License.
 41 */
 42
 43package com.google.maps.extras.markerclusterer
 44{
 45import com.google.maps.LatLng;
 46import com.google.maps.MapEvent;
 47import com.google.maps.interfaces.IMap;
 48import com.google.maps.interfaces.IPane;
 49import com.google.maps.interfaces.IPaneManager;
 50import com.google.maps.overlays.OverlayBase;
 51
 52import flash.display.Bitmap;
 53import flash.display.Loader;
 54import flash.events.Event;
 55import flash.geom.Point;
 56import flash.net.URLRequest;
 57import flash.text.TextField;
 58import flash.text.TextFormat;
 59import flash.text.TextFormatAlign;
 60
 61
 62/**
 63 * 
 64 * This is a presentation class for <code>Cluster</code>.
 65 * The current implementation is to load images for different level.
 66 * Later, it can be implemented with other possibilities.
 67 * 
 68 * 
 69 * Update: 
 70 * 	2010-02-11
 71 * 		Now it works with Flash, that means it also works for Flex.
 72 * 	2010-02-13
 73 * 		Make it formal as overlay .e.g. create and destroy content as needed - 
 74 * 			through MapEvent.OVERLAY_ADDED, and MapEvent.OVERLAY_REMOVED events.
 75 */  
 76internal class ClusterMarker extends OverlayBase
 77{
 78	private var _latlng 	: LatLng;
 79	private var _count		: int;
 80	private var _styles 	: Array;
 81//	private var text_ 		: String;
 82//	private var padding_	: Number;
 83
 84	
 85//	private var imageLoader	: Image;
 86//	private var label		: Label;
 87	
 88	public function ClusterMarker (latlng : LatLng, count:int , styles : Array, padding : Number)
 89	{
 90		_latlng	= latlng;
 91		_styles = styles;
 92		_count 	= count;
 93		
 94		this.addEventListener(MapEvent.OVERLAY_ADDED, onOverlayAdded);
 95		this.addEventListener(MapEvent.OVERLAY_REMOVED, onOverlayRemoved);
 96		
 97	}
 98	
 99	private var _ld:Loader;
100	private var _tf:TextField;
101	
102	private function onOverlayAdded(event:MapEvent):void{
103		var index 	: int = 0;
104		var dv		: int = _count;
105
106		while (dv != 0) {
107			dv = dv / 10;
108			index ++;
109		}
110		
111		if (_styles.length < index) {
112			index = _styles.length;
113  		}
114		
115		var url_ :String		= _styles[index - 1].url;
116//		textColor_ 						= styles[index - 1].opt_textColor;
117//		anchor_ 						= styles[index - 1].opt_anchor;
118
119		var text_:String 		= String(_count);
120//		padding_ 						= padding;
121/* 		
122		imageLoader						= new Image();
123		imageLoader.autoLoad            = true;
124		imageLoader.source 				= url_; 
125		imageLoader.scaleContent 		= false;
126		imageLoader.addEventListener(Event.COMPLETE, completeHandler);
127		addChild(imageLoader);
128		 */
129		var req:URLRequest = new URLRequest(url_);
130		_ld = new Loader;
131		_ld.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
132		_ld.load(req);
133		
134		this.addChild(_ld);
135		
136		
137/* 	
138@20100211
139Previous code, for Flex only!	
140		label							= new Label();
141		label.setStyle("textAlign", "center");
142		label.setStyle("color", "0x00FF00");
143		label.setStyle("font", "Verdana");
144		label.setStyle("bold", "true");
145		label.selectable                = false;
146		label.text 						= text_;
147		
148		addChild(label);
149 */
150		var format :TextFormat = new TextFormat;
151		format.align = TextFormatAlign.CENTER;
152		format.color = 0xFFFFFF;
153		format.font = 'Verdana';
154		format.bold = true;
155		
156		this._tf = new TextField;
157		_tf.selectable = false;
158		_tf.text = text_;
159		_tf.setTextFormat(format);
160		
161		this.addChild(_tf);
162	}
163	
164	private function onOverlayRemoved(event:MapEvent):void{
165		this.removeChild(_ld);
166		_ld = null;
167		
168		this.removeChild(_tf);
169		_tf = null;
170		
171	}
172	
173	private function completeHandler(event : Event) : void
174	{		
175	//	imageLoader.width = event.currentTarget.content.width;
176	//	imageLoader.height = event.currentTarget.content.height;	
177		var content:Bitmap = event.currentTarget.content;
178		_ld.width = content.width;
179		_ld.height = content.height;	
180	
181	//	event.currentTarget.move(imageLoader.width/-2, imageLoader.height/-2);
182		_ld.x = _ld.width / -2;
183		_ld.y = _ld.height / -2;
184		
185	/* 	label.width 	= imageLoader.width;
186		label.height 	= 14;
187		label.x         = imageLoader.width / -2;
188		label.y 		= 0 - (label.height / 2);
189		label.visible 	= true; */
190		this._tf.width = _ld.width;
191		this._tf.height = 16;
192		this._tf.x = - _ld.width / 2;
193		this._tf.y = 0 - (_tf.height/2);
194		
195	}
196	
197	override public function getDefaultPane(map : IMap): IPane
198	{
199		var paneManager	: IPaneManager = map.getPaneManager();
200
201//		return paneManager.getPaneById(PaneId.PANE_MARKER);
202		
203		return null;
204	}
205	
206	override public function positionOverlay(zoomChanged : Boolean): void
207	{
208		this.reposition();
209	}
210	
211/* 	private function remove () : void
212	{
213		parent.removeChild(this);
214	} */
215	/*
216	private function copy () : ClusterMarker
217	{
218		return new ClusterMarker(this.latlng_, this.index_, this.styles_, this.padding_);
219	}
220	*/
221	/**
222	 * 
223	 * Developer should not call this function. 
224	 * It is managed by Cluster.
225	 */ 
226	internal function redraw (force:Boolean) : void
227	{
228		if (!force){
229			return;
230		}
231
232		this.reposition();
233	}
234	
235	private function reposition():void{
236		var pos : Point = this.pane.fromLatLngToPaneCoords(_latlng);
237		x = pos.x;
238		y = pos.y;
239	}
240}
241}