API Google Maps pour Flash : ajouter un zoom basé sur un rectangle de sélection (suite et fin)

Dans les articles précédents :
(API Google Maps pour Flash), on a vu comment préparer et configurer son éditeur pour gérer l’API Google Maps.
(API Google Maps pour Flash (suite)), on a vu comment ajouter des fonctionnalités (contrôles, options, marqueurs, évènements,…).

Pour ce dernier article, on va voir comment ajouter un zoom basé sur un rectangle de sélection, celui ci ne sera actif qu’avec la touche contrôle enfoncé afin de garder la possibilité de déplacer la carte en cliquant dessus avec la souris.
Pour faire ceci, on va devoir :

  • Récupérer la position de la souris au début et à la fin de la zone de sélection.
  • Convertir ces positions en latitude/longitude
  • Définir la taille du rectangle de sélection correspondant à ces latitudes/longitudes
  • Trouver le centre du rectangle de sélection
  • Trouver la valeur de zoom correspondant à la taille du rectangle de sélection
  • Appliquer les nouvelles valeurs


Tout le code utile pour définir le rectangle de sélection et le zoom sur cette zone :

		// Déclarations
		private var _mapZoomPointDebut:Point = null;
		private var _mapZoomLatDebut:LatLng = null;
		private var _mapZoomLatFin:LatLng = null;
 
		private var _spZone:Sprite = null;// Le sprite posé au dessus de la carte qui contiendra le dessin du rectangle de sélection
 
		// évènements
		_map.addEventListener(MapMouseEvent.MOUSE_DOWN, evtMapMouseDown);
		_map.addEventListener(MapMouseEvent.MOUSE_UP, evtMapMouseUp);
		_map.addEventListener(MapMouseEvent.MOUSE_MOVE, evtMapMouseMove);
 
		// -----------------------------------------------------------------------------------
		// EVENEMENTS -> DEFINITION ZONE ET ZOOM SUR ZONE
		// -----------------------------------------------------------------------------------
		private function evtMapMouseDown(ev:MapMouseEvent):void {
			// si la touche controle est enfoncé au moment du clique : enregistrer le point de départ et bloquer le déplacement de la carte
			if ( ev.ctrlKey ) {
				_map.disableDragging();
				_mapZoomLatDebut = ev.latLng;// stockage de la latitude/longitude de départ correspondant à la souris
				_mapZoomPointDebut = new Point(stage.mouseX, stage.mouseY);// stockage de la position de départ de la souris
			}
		}
 
		private function evtMapMouseUp(ev:MapMouseEvent):void {
			// Zoomer sur la zone sélectionné
			// TODO gérer la direction d'ouverture du rectangle pour que le point de départ soit toujours en haut à gauche
			if ( ev.ctrlKey && _map.draggingEnabled() == false ) {
				_spZone.graphics.clear();
				_mapZoomLatFin = ev.latLng;// stockage de la latitude/longitude de fin correspondant à la souris
				var llBound:LatLngBounds = new LatLngBounds(_mapZoomLatDebut, _mapZoomLatFin);// définir la zone sur la carte (latitude/longitude) correspondant au rectangle de sélection
				var c:LatLng = llBound.getCenter();// trouver le centre du rectangle
				var z:Number = _map.getBoundsZoomLevel(llBound);// trouver la valeur de zoom correspondant au rectangle de sélection
				_map.setCenter(c, z);// recentrer et zoomer la carte
			}
			_map.enableDragging();
		}
 
		private function evtMapMouseMove(ev:MapMouseEvent):void {
			// si la touche contrôle est gardé enfoncé pendant le déplacement :  dessiner le rectangle de sélection
			// entre le point de départ et le point courant
			if ( ev.ctrlKey && _map.draggingEnabled() == false ) {
				with (_spZone.graphics) {
					clear();
					lineStyle(2, 0xFF0000, 1);
					beginFill(0x006699, 0.2);
					drawRect(_mapZoomPointDebut.x, _mapZoomPointDebut.y, stage.mouseX - _mapZoomPointDebut.x, stage.mouseY - _mapZoomPointDebut.y);
					endFill();
				}
			}
		}

Voici le SWF incluant les fonctionnalités des articles précédents ainsi que le zoom basé sur le rectangle de sélection :

Pour utiliser le zoom basé sur le rectangle de sélection, il vous suffit de garder la touche contrôle enfoncé et d’utiliser la souris pour définir la zone.


code complet de l’exemple :

package {
	import com.google.maps.controls.MapTypeControl;
	import com.google.maps.controls.NavigationControl;
	import com.google.maps.controls.OverviewMapControl;
	import com.google.maps.controls.ScaleControl;
	import com.google.maps.controls.ScaleControlOptions;
	import com.google.maps.LatLng;
	import com.google.maps.LatLngBounds;
	import com.google.maps.Map;
	import com.google.maps.MapEvent;
	import com.google.maps.MapMouseEvent;
	import com.google.maps.MapOptions;
	import com.google.maps.MapType;
	import com.google.maps.overlays.Marker;
	import com.google.maps.overlays.MarkerOptions;
	import com.google.maps.overlays.Polyline;
	import com.google.maps.overlays.PolylineOptions;
	import com.google.maps.styles.StrokeStyle;
 
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.text.TextFormat;
 
 
 
	/**
	 * Test des possibilités de l'API google map
	 * @author Lorenzo
	 */
	public class MainComplet extends Sprite {
		// -----------------------------------------------------------------------------------
		// DECLARATIONS
		// -----------------------------------------------------------------------------------
 
		private var _map:Map = null;
 
		private var _positionRoissy:LatLng = new LatLng(48.790367,2.656885);
		private var _positionGarePontault:LatLng = new LatLng(48.805843, 2.617828);
		private var _positionCarrefourPontault:LatLng = new LatLng(48.77617, 2.608611);
		private var _positionCentre:LatLng = new LatLng(48.793764,2.632756);
 
		private var _mapZoomPointDebut:Point = null;
		private var _mapZoomLatDebut:LatLng = null;
		private var _mapZoomLatFin:LatLng = null;
 
		private var _spZone:Sprite = null;
 
 
 
 
		// -----------------------------------------------------------------------------------
		// CONSTRUCTEUR
		// -----------------------------------------------------------------------------------
		public function MainComplet():void {
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
 
		private function init(e:Event = null):void {
			removeEventListener(Event.ADDED_TO_STAGE, init);
 
 
			// ---------
			stage.scaleMode = "noScale";
			stage.align = "LT";
			stage.quality = "medium";
 
			// définition de la carte, de ces options et évenements
			_map = new Map();
			_map.language = "fr_FR";
			_map.countryCode = "FR";
			_map.key = "ABQIAAAAvwdr5PrLsm228aByyJiTFRQ5NISJ_vEU2QZeuqsHywIYKJUzMhS0KqAO5rT_XJ07lAzKRjs3aZG6eQ";
			_map.setSize(new Point(stage.stageWidth, stage.stageHeight));
			_map.addEventListener(MapEvent.MAP_READY, evtMapReady);
			_map.addEventListener(MapEvent.MAP_PREINITIALIZE, evtMapPreinitialize);
			_map.addEventListener(MouseEvent.MOUSE_WHEEL, evtMapMouseWheel);
			_map.addEventListener(MapMouseEvent.MOUSE_DOWN, evtMapMouseDown);
			_map.addEventListener(MapMouseEvent.MOUSE_UP, evtMapMouseUp);
			_map.addEventListener(MapMouseEvent.MOUSE_MOVE, evtMapMouseMove);
			_map.x = 0;
			_map.y = 0;
			this.addChild(_map);
 
			// ---------
			_spZone = new Sprite();
			_spZone.x = 0;
			_spZone.y = 0;
			this.addChild(_spZone);
 
 
			// ---------
			stage.addEventListener(Event.RESIZE, evtStageResize);
		}
 
 
 
 
		// -----------------------------------------------------------------------------------
		// EVENEMENTS -> DEFINITION ZONE ET ZOOM SUR ZONE
		// -----------------------------------------------------------------------------------
		private function evtMapMouseDown(ev:MapMouseEvent):void {
			// si la touche controle est enfoncé au moment du clique : enregistrer le point de départ et bloquer le déplacement de la carte
			if ( ev.ctrlKey ) {
				_map.disableDragging();
				_mapZoomLatDebut = ev.latLng;
				_mapZoomPointDebut = new Point(stage.mouseX, stage.mouseY);
			}
		}
 
		private function evtMapMouseUp(ev:MapMouseEvent):void {
			// Zoomer sur la zone sélectionné
			if ( ev.ctrlKey && _map.draggingEnabled() == false ) {
				_spZone.graphics.clear();
				_mapZoomLatFin = ev.latLng;
				var llBound:LatLngBounds = new LatLngBounds(_mapZoomLatDebut, _mapZoomLatFin);
				var c:LatLng = llBound.getCenter();
				var z:Number = _map.getBoundsZoomLevel(llBound);
				_map.setCenter(c, z);
			}
			_map.enableDragging();
		}
 
		private function evtMapMouseMove(ev:MapMouseEvent):void {
			// si la touche controle est gardé enfoncé pendant le déplacement :  dessiner la zone de zoom
			if ( ev.ctrlKey && _map.draggingEnabled() == false ) {
				with (_spZone.graphics) {
					clear();
					lineStyle(2, 0xFF0000, 1);
					beginFill(0x006699, 0.2);
					drawRect(_mapZoomPointDebut.x, _mapZoomPointDebut.y, stage.mouseX - _mapZoomPointDebut.x, stage.mouseY - _mapZoomPointDebut.y);
					endFill();
				}
			}
		}
 
 
 
		// -----------------------------------------------------------------------------------
		// EVENEMENT -> REDIMENSIONNEMENT STAGE (redéfinir la taille de la map)
		// -----------------------------------------------------------------------------------
		private function evtStageResize(ev:Event):void {
			_map.setSize(new Point(stage.stageWidth, stage.stageHeight));
		}
 
 
 
		// -----------------------------------------------------------------------------------
		// EVENEMENT -> INITIALISATION MAP (définition des options)
		// -----------------------------------------------------------------------------------
		private function evtMapPreinitialize(ev:MapEvent):void {
			var mapO:MapOptions = new MapOptions();
			mapO.zoom = 13;
			mapO.center = _positionCentre;
			mapO.mapType = MapType.HYBRID_MAP_TYPE;
			_map.setInitOptions(mapO);
		}
 
 
 
		// -----------------------------------------------------------------------------------
		// EVENEMENT -> CHARGEMENT MAP (ajout des marqueurs, des lignes et des controles)
		// -----------------------------------------------------------------------------------
		private function evtMapReady(ev:MapEvent):void {
			// ajout de 3 marqueurs a 3 positions différentes
			var m:MarkerOptions = new MarkerOptions( 
			{ 
				fillStyle: { color:0xFF0000 },
				strokeStyle: { color:0, thickness:1 },
				tooltip:"Roissy en brie",
				radius:20,
				hasShadow:true,
				draggable:false
			}
			);
			_map.addOverlay(new Marker(_positionRoissy, m));
 
			m = new MarkerOptions( 
			{ 
				fillStyle: { color:0x00FF00 },
				strokeStyle: { color:0, thickness:1 },
				tooltip:"la gare de pontault",
				radius:20,
				hasShadow:true,
				draggable:false
			}
			);
			_map.addOverlay(new Marker(_positionGarePontault, m));
 
			m = new MarkerOptions( 
			{ 
				fillStyle: { color:0x0000FF },
				strokeStyle: { color:0, thickness:1 },
				tooltip:"carrefour de pontault",
				radius:20,
				hasShadow:true,
				draggable:false
			}
			);
			_map.addOverlay(new Marker(_positionCarrefourPontault, m));
 
			// dessiner des lignes entre les 3 positions
			var po:PolylineOptions = new PolylineOptions({ strokeStyle: new StrokeStyle({
				color: 0xFF0000,
				thickness: 4,
				alpha: 0.7})
			});
			var pl:Polyline = new Polyline([_positionRoissy, _positionGarePontault, _positionCarrefourPontault, _positionRoissy], po);
			_map.addOverlay(pl);
 
			// ajout des controles
			_map.addControl(new MapTypeControl());
			_map.addControl(new OverviewMapControl());
			_map.addControl(new NavigationControl());
 
			var sco:ScaleControlOptions = new ScaleControlOptions();
			sco.labelFormat = new TextFormat('Arial', 12, 0xFFFFFF, true);
			sco.units = ScaleControlOptions.UNITS_METRIC_ONLY;
			_map.addControl(new ScaleControl(sco));
		}
 
 
 
		// -----------------------------------------------------------------------------------
		// EVENEMENT -> ZOOM SUR LA CARTE AVEC LA ROULETTE DE LA SOURIS
		// -----------------------------------------------------------------------------------
		private function evtMapMouseWheel(ev:MouseEvent):void {
			// recuperer le zoom actuel et l'incrémenter ou le décrementer suivant la direction de la roulette de la souris
			var z:Number = _map.getZoom() + (ev.delta > 1 ? 1 : -1);
			z = (z > 20 ? 20 : z);
 
			// Zoomer sur la carte en utilisant son centre
			//_map.setCenter(_map.getCenter(), z);
 
			// Zoomer sur la carte en la centrant sur la position de la souris
			var pos:LatLng = _map.fromViewportToLatLng(new Point(_map.mouseX, _map.mouseY));
			_map.setCenter(pos, z);
		}
	}
}


Les possibilités de cette API sont innombrables, vos clients apprécieront surement ses fonctionnalités ;)

Laisser un commentaire

*