package tripvisUI { import com.google.maps.LatLng; import com.google.maps.Map; import com.google.maps.MapEvent; import com.google.maps.MapMoveEvent; import com.google.maps.controls.MapTypeControl; import com.google.maps.controls.ZoomControl; import com.google.maps.overlays.Marker; import com.google.maps.overlays.MarkerOptions; import com.google.maps.services.ClientGeocoder; import com.google.maps.services.GeocodingEvent; import com.google.maps.services.GeocodingResponse; import com.google.maps.services.Placemark; import comp.MovablePanel; import flash.events.KeyboardEvent; import flash.events.MouseEvent; import flash.ui.Keyboard; import flash.utils.Dictionary; import mx.collections.ArrayCollection; import mx.containers.Canvas; import mx.controls.Alert; import mx.controls.Button; import mx.controls.CheckBox; import mx.controls.Image; import mx.controls.TextInput; import mx.effects.Fade; import mx.events.EffectEvent; import tripvisModel.MapViewport; import tripvisModel.SimpleTripItem; import tripvisModel.TripItemType; import tripvisModel.TripVisModel; import tripvisModel.controllers.MapController; import tripvisModel.controllers.MapControllerEvent; import tripvisUI.events.TripmapEvent; import tripvisUI.languages.LanguageDirector; [Event(name="tripmapReady", type="tripvisUI.events.TripmapEvent")] [Event(name="selectMapTripItem", type="tripvisUI.events.TripmapEvent")] [Event(name="tripmapMapChanged", type="tripvisUI.events.TripmapEvent")] public class TripMap extends Canvas { private var _googleMap: Map; private var _searchTextInput: TextInput; private var _overlayImage: Image; private var _introImage: Image; private var _hotelCheckBox: CheckBox; private var _landmarkCheckBox: CheckBox; private var _eatingCheckBox: CheckBox; private var _geocoder: ClientGeocoder; private var _isMapReady: Boolean = false; private var _mapTripItems: ArrayCollection; private var _visibleMapTripItems: ArrayCollection; private var _mapTripItem2Marker: Dictionary = new Dictionary(); private var _fadeIn: Fade; private var _fadeOut: Fade; public function TripMap() { super(); _mapTripItems = new ArrayCollection(); _visibleMapTripItems = new ArrayCollection(); _fadeIn = new Fade(); _fadeIn.alphaFrom = 0; _fadeIn.alphaTo = 1; _fadeOut = new Fade(); _fadeOut.alphaFrom = 1; _fadeOut.alphaTo = 0; } override protected function createChildren():void { super.createChildren(); _googleMap = new Map(); _googleMap.percentHeight = 100; _googleMap.percentWidth = 100; _googleMap.key = "ABQIAAAARn-9VZzi9b6hoik-_GFUuBRHqkFQ33Y2cju3AGmX5-jY3cJ1bRSDYkX_fwR2r56iIbMCdmcJYm3rNQ"; _googleMap.url = "http://neat.be/adobe_air_thesis/"; _googleMap.language = LanguageDirector.instance.language.mapGoogleLanguage; _googleMap.addEventListener(MapEvent.MAP_READY, googleMap_ready); this.addChild(_googleMap); // search panel: var searchPanel: MovablePanel = new MovablePanel(); searchPanel.title = LanguageDirector.instance.language.mapFindDestination; searchPanel.x = 90; searchPanel.y = 10; searchPanel.width = 330; searchPanel.height = 80; searchPanel.layout = "absolute"; searchPanel.styleName = "searchPanel"; var searchButton: Button = new Button(); searchButton.label = LanguageDirector.instance.language.search; searchButton.x = 236; searchButton.y = 10; searchButton.addEventListener(MouseEvent.CLICK, searchButton_click); _searchTextInput = new TextInput(); _searchTextInput.x = 10; _searchTextInput.y = 10; _searchTextInput.width = 220; _searchTextInput.addEventListener(KeyboardEvent.KEY_DOWN, searchText_keyDown); searchPanel.addChild(searchButton); searchPanel.addChild(_searchTextInput); this.addChild(searchPanel); // filter panel: var filterPanel: MovablePanel = new MovablePanel(); filterPanel.title = LanguageDirector.instance.language.mapFilterOn; filterPanel.width = 163; filterPanel.height = 122; filterPanel.layout = "absolute"; filterPanel.setStyle('bottom', 10); filterPanel.setStyle('left', 10); filterPanel.styleName = "searchPanel"; _hotelCheckBox = new CheckBox(); _hotelCheckBox.label = LanguageDirector.instance.language.hotels; _hotelCheckBox.x = 10; _hotelCheckBox.y = 10; _hotelCheckBox.selected = true; _hotelCheckBox.addEventListener(MouseEvent.CLICK, filterCheckBoxes_changed); _landmarkCheckBox = new CheckBox(); _landmarkCheckBox.label = LanguageDirector.instance.language.landmarks; _landmarkCheckBox.x = 10; _landmarkCheckBox.y = 40; _landmarkCheckBox.selected = true; _landmarkCheckBox.addEventListener(MouseEvent.CLICK, filterCheckBoxes_changed); _eatingCheckBox = new CheckBox(); _eatingCheckBox.label = LanguageDirector.instance.language.restaurants; _eatingCheckBox.x = 10; _eatingCheckBox.y = 70; _eatingCheckBox.selected = true; _eatingCheckBox.addEventListener(MouseEvent.CLICK, filterCheckBoxes_changed); filterPanel.addChild(_hotelCheckBox); filterPanel.addChild(_landmarkCheckBox); filterPanel.addChild(_eatingCheckBox); this.addChild(filterPanel); //overlay images: _overlayImage = new Image(); _overlayImage.source = "icons/map_blur.png"; _overlayImage.percentWidth = 100; _overlayImage.percentHeight = 100; _overlayImage.scaleContent = true; _overlayImage.maintainAspectRatio = false; this.addChild(_overlayImage); _introImage = new Image(); _introImage.source = LanguageDirector.instance.language.whereToGo; _introImage.setStyle('horizontalCenter', 0); this.addChild(_introImage); } private function googleMap_ready(event: MapEvent): void { _googleMap.addControl(new ZoomControl()); _googleMap.addControl(new MapTypeControl()); // zoom to level 2: _googleMap.setCenter(_googleMap.getCenter(), 2); _googleMap.enableScrollWheelZoom(); _googleMap.enableContinuousZoom(); // Nodig om van een adres een locatie te maken _geocoder = new ClientGeocoder(); _geocoder.addEventListener(GeocodingEvent.GEOCODING_SUCCESS, geocoder_geocodingSuccess); _geocoder.addEventListener(GeocodingEvent.GEOCODING_FAILURE, geocoder_geocodingFailure); // registeren op de MapController: var mapController: MapController = TripVisModel.instance.mapController; mapController.addEventListener(MapControllerEvent.TRIP_ITEM_ADDED, mapController_TripItemAdded); mapController.addEventListener(MapControllerEvent.TRIP_ITEMS_CLEARED, mapController_TripItemsCleared); mapController.addEventListener(MapControllerEvent.TRIP_ITEM_REMOVED, mapController_TripItemRemoved); // if map is moved/zoomed: _googleMap.addEventListener(MapMoveEvent.MOVE_END, googleMap_moveEnd); // Map is ready: _isMapReady = true; dispatchEvent( new TripmapEvent("tripmapReady") ); _introImage.addEventListener(MouseEvent.MOUSE_OVER, introImage_mouseOver); } //Visuele fade in/out handlers: private function introImage_mouseOver(event: MouseEvent): void { var fadeOutintro: Fade = new Fade(); fadeOutintro.alphaFrom = 1; // volledig zichtbaar fadeOutintro.alphaTo = 0; // onzichtbaar fadeOutintro.addEventListener(EffectEvent.EFFECT_END, fadeOutintro_end); fadeOutintro.play([_introImage, _overlayImage]); } private function fadeOutintro_end(Event: EffectEvent): void { _introImage.visible = false; _overlayImage.visible = false; _introImage.enabled = false; _overlayImage.enabled = false; } // Search functions handlers: private function searchButton_click(event: MouseEvent): void { _geocoder.geocode(_searchTextInput.text); } private function searchText_keyDown(event: KeyboardEvent): void { if (event.keyCode == Keyboard.ENTER) _geocoder.geocode(_searchTextInput.text); } // Geocoder Handlers: private function geocoder_geocodingSuccess(event: GeocodingEvent): void { var result: Placemark = GeocodingResponse(event.response).placemarks[0]; _googleMap.setCenter(result.point, 13); } private function geocoder_geocodingFailure(event: GeocodingEvent): void { Alert.show(LanguageDirector.instance.language.mapError + ": " + event.name + " " + LanguageDirector.instance.language.mapLocationNotFound); } // Map moved/zoomed private function googleMap_moveEnd(event: MapMoveEvent): void { dispatchEvent( new TripmapEvent('tripmapMapChanged') ); } //MapController Handlers: private function mapController_TripItemAdded(event: MapControllerEvent): void { var simpleTripItem: SimpleTripItem = event.simpleTripItem; if (isMapReady) { var mapTripItem: MapTripitem = new MapTripitem(simpleTripItem); addMapTripItem(mapTripItem); //trace("aantal visible maptripitems: " + _visibleMapTripItems.length.toString()); } else { throw new Error("Cannot add TripItem: Map is not ready"); } } private function mapController_TripItemRemoved(event: MapControllerEvent): void { var removedTripItem: SimpleTripItem = event.simpleTripItem; var removedMapTripItem: MapTripitem = getMapTripItemFromSimpleTripItem(removedTripItem); hideMapTripItem(removedMapTripItem); _mapTripItems.removeItemAt( _mapTripItems.getItemIndex(removedMapTripItem) ); } private function mapController_TripItemsCleared(event: MapControllerEvent): void { for (var i: int = 0; i < _mapTripItems.length; i++) { hideMapTripItem(_mapTripItems[i]); } _mapTripItems.removeAll(); } private function addMapTripItem(mapTripItem: MapTripitem): void { // als het een totaal nieuwe MapTripitem is: if ( !_mapTripItems.contains(mapTripItem) ) _mapTripItems.addItem(mapTripItem); // als hij niet gefilterd is if ( ! isFiltered(mapTripItem) ) { // en als hij al niet op de map staat: if ( !_visibleMapTripItems.contains(mapTripItem) ) { // voeg de marker toe aan de google map: addMarkerToMap(mapTripItem); _visibleMapTripItems.addItem(mapTripItem); // click handler toevoegen aan de MapTripItem: mapTripItem.addEventListener(MouseEvent.CLICK, aMapTripItem_click); // fade de MapTripItem in _fadeIn.play([mapTripItem]); } } } private function addMarkerToMap(mapTripItem: MapTripitem): void { var markerOptions: MarkerOptions = new MarkerOptions(); markerOptions.hasShadow = false; markerOptions.icon = mapTripItem; markerOptions.iconAlignment = MarkerOptions.ALIGN_HORIZONTAL_CENTER + MarkerOptions.ALIGN_VERTICAL_CENTER; var marker: Marker = new Marker(new LatLng(mapTripItem.simpleTripItem.location.latitude, mapTripItem.simpleTripItem.location.longitude), markerOptions); _googleMap.addOverlay(marker); //referentie naar marker bijhouden _mapTripItem2Marker[mapTripItem] = marker; } private function isFiltered(mapTripItem: MapTripitem): Boolean { switch(mapTripItem.simpleTripItem.type) { case TripItemType.HOTEL: if (_hotelCheckBox.selected == false) return true; break; case TripItemType.LANDMARK: if (_landmarkCheckBox.selected == false) return true; break; case TripItemType.EATINGPLACE: if (_eatingCheckBox.selected == false) return true; break; } return false; } private function hideMapTripItem(mapTripItem: MapTripitem): void { if ( _visibleMapTripItems.contains( mapTripItem ) ) { _visibleMapTripItems.removeItemAt( _visibleMapTripItems.getItemIndex(mapTripItem) ); mapTripItem.removeEventListener(MouseEvent.CLICK, aMapTripItem_click); var fadeTripItemOut: Fade = new Fade(); fadeTripItemOut.alphaFrom = 1; fadeTripItemOut.alphaTo = 0; fadeTripItemOut.addEventListener(EffectEvent.EFFECT_END, function(event: EffectEvent):void { var marker: Marker = _mapTripItem2Marker[mapTripItem]; _googleMap.removeOverlay(marker); delete _mapTripItem2Marker[mapTripItem]; } ); fadeTripItemOut.play([mapTripItem]); } } private function getMapTripItemFromSimpleTripItem(simpleTripItem: SimpleTripItem): MapTripitem { for each( var mapTripItem: MapTripitem in _mapTripItems) { var s: SimpleTripItem = mapTripItem.simpleTripItem; if (s == simpleTripItem) return mapTripItem; } return null; } // Wanneer er op een MapTripItem geklikt wordt: private function aMapTripItem_click(event: MouseEvent): void { var mapTripItem: MapTripitem = (event.currentTarget as MapTripitem); dispatchEvent( new TripmapEvent("selectMapTripItem", mapTripItem) ); } // Wanneer er iets aan de filter opties veranderd: private function filterCheckBoxes_changed(event: MouseEvent): void { filterTripItems(_hotelCheckBox.selected, _landmarkCheckBox.selected, _eatingCheckBox.selected); } public function filterTripItems(showHotels: Boolean, showLandmarks: Boolean, showRestaurants: Boolean): void { for each (var mapTripItem: MapTripitem in _mapTripItems) { if (isFiltered(mapTripItem)) { hideMapTripItem(mapTripItem); } else { addMapTripItem(mapTripItem); } } } // MapViewport: public function getMapViewport(): MapViewport { return new MapViewport( _googleMap.width, _googleMap.height, _googleMap.getZoom(), _googleMap.getCenter(), _googleMap.getLatLngBounds() ); } // Getters & Setters: public function get isMapReady(): Boolean { return this._isMapReady; } } }