>>> REFACTOR: something odd about accessing map.tileparams here... theMap.tileset.blocks=[new RegExp("google","i")]; // hard-coded block on Google tiles theMap.tileset.init(theMap.tileparams, false, params['background_dim'] ==null ? true : params['background_dim'], params['background_sharpen']==null ? false : params['background_sharpen']); // Add core data layer // >>>> REFACTOR: shouldn't be hardcoded to XMLConnection var conn:Connection = new XMLConnection("Main", params['api'], params['policy'], params); conn.addEventListener(Connection.LOAD_STARTED, onDataStart); conn.addEventListener(Connection.LOAD_COMPLETED, onDataComplete); conn.addEventListener(Connection.SAVE_STARTED, onDataStart); conn.addEventListener(Connection.SAVE_COMPLETED, onDataComplete); conn.addEventListener(Connection.DATA_DIRTY, onDataDirty); conn.addEventListener(Connection.DATA_CLEAN, onDataClean); conn.addEventListener(MapEvent.ERROR, onMapError); conn.addEventListener(AttentionEvent.ATTENTION, onAttention); conn.addEventListener(AttentionEvent.ALERT, onAlert); // >>>> REFACTOR: shouldn't be trying to find out stylesheet from here theMap.addLayer(conn,params['styleurl'] ? params['styleurl'] : 'stylesheets/potlatch.css',false); // Auto-load vector backgrounds from config theMap.addEventListener(MapEvent.INITIALISED, function(e:Event):void { VectorBackgrounds.instance().init(theMap); }); // Set start position of map // >>>> REFACTOR: what happens if lat/lon/zoom not supplied? (Hurleston GPX case) theMap.init(params['lat'], params['lon'], params['zoom']); // add attribution/logo sprite var overlay:Sprite=new Sprite(); var attribution:TextField=new TextField(); attribution.width=220; attribution.height=300; attribution.multiline=true; attribution.wordWrap=true; attribution.selectable=false; attribution.defaultTextFormat=new TextFormat("_sans", 9, 0, false, false, false); overlay.addChild(attribution); var terms:TextField=new TextField(); terms.width=200; terms.height=15; terms.selectable=false; terms.defaultTextFormat=new TextFormat("_sans", 9, 0, false, false, true); overlay.addChild(terms); _root.addChild(overlay); // mouse-up handler attached to stage, so the user can release outside the map stage.addEventListener(MouseEvent.MOUSE_UP, theMap.mouseUpHandler); Globals.vars.map_area.addEventListener(MouseEvent.MOUSE_MOVE, theMap.mouseMoveHandler); Globals.vars.map_area.addEventListener(MouseEvent.MOUSE_DOWN, theMap.mouseDownHandler); // initialise imagery and stylesheets Imagery.instance().init(theMap, overlay, yahoo); Stylesheets.instance().init(theMap); Imagery.instance().addEventListener(MapEvent.BUMP, bumpHandler); // keyboard event attached to stage stage.addEventListener(KeyboardEvent.KEY_UP, theMap.keyUpHandler); // mouse-position listener for co-ordinate display theMap.addEventListener(MapEvent.MOUSE_MOVE, mouseoverHandler); // position toolbox toolbox=Toolbox(PopUpManager.createPopUp(this,Toolbox,false)); toolbox.init(theController); toolbox.x=stage.stageWidth-toolbox.width-5; toolbox.y=stage.stageHeight-toolbox.height-5; // add debug field var t:TextField=new TextField(); t.width=500; t.height=150; t.border=true; t.multiline=true; _root.addChild(t); Globals.vars.debug=t; t.visible = loaderInfo.parameters["show_debug"] == 'true'; Globals.vars.root=theMap; // just for the addDebug function theController = new EditController(theMap, tagViewer, toolbox); theController.setActive(); // set the access token from saved cookie var tokenObject:SharedObject = SharedObject.getLocal("access_token"); conn.setAccessToken(tokenObject.data["oauth_token"], tokenObject.data["oauth_token_secret"]); // Load any requested GPX track if (loaderInfo.parameters['gpx']) { var id:Number = loaderInfo.parameters['gpx']; if (conn.hasAccessToken()) { loadTrace(id); } else { SaveManager.ensureAccess(function ():void { loadTrace(id); }, conn); } } // Load arbitrary GPX from provided URL if (loaderInfo.parameters['gpx_url']) { var vectorlayer:VectorLayer=new VectorLayer(name,theMap,"stylesheets/gpx.css"); vectorlayer.url=loaderInfo.parameters['gpx_url']; var gpx:GpxImporter=new GpxImporter(vectorlayer, vectorlayer.paint, [vectorlayer.url], function(success:Boolean,message:String=null):void { if (!success) return; // >>>> REFACTOR: vectorlayer commented out // theMap.addVectorLayer(vectorlayer); dispatchEvent(new Event("layers_changed")); }, false); } // create GPS trackloader trackLoader=new TrackLoader(theMap,conn.apiBase); // Force authentication on startup, if required // force_auth == force => checks for access token, and displays OAuth panel if needed var force_auth:String = loaderInfo.parameters["force_auth"]; if (!conn.hasAccessToken() && force_auth == 'force') { SaveManager.ensureAccess(onAccessChecked, conn); } // show help dialog on startup, if required // show_help == always => on every startup // show_help == once => show on first startup only var show_help:String = loaderInfo.parameters["show_help"]; if (show_help == 'always' || (show_help == 'once' && obj.data["help_shown"] != "true")) { new HelpDialog().init(); } // Check if Tiger highlighting should be enabled from saved object Globals.vars.highlightTiger = obj.data['tiger_highlighted']; } public function onMapError(mapEvent:MapEvent):void { var buttons:uint=0; if (mapEvent.params.no) { trace("no is set"); } if (mapEvent.params.yes ) buttons|=mx.controls.Alert.YES; if (mapEvent.params.no ) buttons|=mx.controls.Alert.NO; if (mapEvent.params.cancel ) buttons|=mx.controls.Alert.CANCEL; if (mapEvent.params.ok || buttons==0) buttons|=mx.controls.Alert.OK; trace("showing alert with "+buttons); Alert.show(mapEvent.params.message, 'Error', buttons, null, function(closeEvent:CloseEvent):void { switch (closeEvent.detail) { case mx.controls.Alert.CANCEL: mapEvent.params.cancel(); break; //fixme? this gets called if user presses escape, even if there's no cancel button. case mx.controls.Alert.YES: mapEvent.params.yes(); break; case mx.controls.Alert.NO: mapEvent.params.no(); break; default: if (mapEvent.params.ok) mapEvent.params.ok(); } }); } /** Highlight an entity in response to an 'attention' event */ public function onAttention(event:AttentionEvent):void { var entity:Entity=event.entity; if (entity is Relation) { // If it's a relation, just bring up the editor panel var panel:RelationEditorPanel = RelationEditorPanel( PopUpManager.createPopUp(Application(Application.application), RelationEditorPanel, true)); panel.setRelation(entity as Relation); PopUpManager.centerPopUp(panel); return; } var lat:Number, lon:Number; var panTo:Boolean=true; if (entity is Way) { // If it's a way, find if it's on-screen for (var i:uint=0; i0 && savecount>0) { dataWorking.text="Loading/saving..."; } else if (loadcount>0) { dataWorking.text="Loading data..."; } else if (savecount>0) { dataWorking.text="Saving data..."; } else { dataWorking.text=""; } dataWorking.visible=(dataWorking.text!=""); } private function onDataDirty(event:Event):void { saveButton.enabled=true; if (ExternalInterface.available) { ExternalInterface.call("markChanged", false); } } private function onDataClean(event:Event):void { saveButton.enabled=false; if (ExternalInterface.available) { ExternalInterface.call("markChanged", true); } } private function scaleHandler(event:MapEvent):void { dispatchEvent(new Event("rescale")); } [Bindable(event="rescale")] private function getScale():String { return String(theMap.scale); } private function dragEnterHandler(event:DragEvent):void { // Get the drop target component from the event object. var dropTarget:Canvas=event.currentTarget as Canvas; // Accept the drag only if the user is dragging poi with tags if (event.dragSource.hasFormat('tags')) { DragManager.acceptDragDrop(dropTarget); } } private function dragDropHandler(event:DragEvent):void { // Deselect the dragged icon if (event.dragSource.dataForFormat('container')) { event.dragSource.dataForFormat('container').selectedItem=-1; } // Get the tags var tags:Array = event.dragSource.dataForFormat('tags') as Array; // If you dnd quick enough, this exposes a flex bug and event.stageX/Y become negative. // Take the mouse positions from a displayObject's stage for consistent results. var mapLoc:Point = Globals.vars.root.globalToLocal(new Point(event.target.stage.mouseX, event.target.stage.mouseY)); var lat:Number = Globals.vars.root.coord2lat(mapLoc.y); var lon:Number = Globals.vars.root.coord2lon(mapLoc.x); var createAction:CompositeUndoableAction = new CompositeUndoableAction("Create POI"); var conn:Connection = theMap.editableLayer.connection; var node:Node = conn.createNode({}, lat, lon, createAction.push); for each ( var tag:Object in tags ) { node.setTag(tag.k, tag.v, createAction.push); } conn.registerPOI(node); MainUndoStack.getGlobalStack().addAction(createAction); theController.setState(new SelectedPOINode(node)); } /* Called when forcing an initial access token check. */ private function onAccessChecked():void { // Floaty panel message "You now have access"; } private function loadTrace(id:Number):void { var conn:Connection = theMap.editableLayer.connection; conn.addEventListener(Connection.TRACES_LOADED, function (e:Event):void { for each (var trace:Trace in conn.getTraces()) { if (trace.id == id) { trace.addToMap(); } } }); conn.fetchUserTraces(); } ]]>