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