beginning of vector background layers. And a whole load of other stuff too
authorRichard Fairhurst <richard@systemed.net>
Fri, 19 Mar 2010 14:11:42 +0000 (14:11 +0000)
committerRichard Fairhurst <richard@systemed.net>
Fri, 19 Mar 2010 14:11:42 +0000 (14:11 +0000)
24 files changed:
TODO.txt
net/systemeD/halcyon/Elastic.as
net/systemeD/halcyon/EntityUI.as
net/systemeD/halcyon/Map.as
net/systemeD/halcyon/MapPaint.as [new file with mode: 0644]
net/systemeD/halcyon/NodeUI.as
net/systemeD/halcyon/WayBitmapFiller.as
net/systemeD/halcyon/WayUI.as
net/systemeD/halcyon/connection/Connection.as
net/systemeD/halcyon/connection/Entity.as
net/systemeD/halcyon/styleparser/MapCSS.as
net/systemeD/halcyon/styleparser/RuleSet.as
net/systemeD/halcyon/vectorlayers/CustomVectorLayer.as [new file with mode: 0644]
net/systemeD/halcyon/vectorlayers/SimpleVectorLayer.as [new file with mode: 0644]
net/systemeD/halcyon/vectorlayers/VectorLayer.as [new file with mode: 0644]
net/systemeD/potlatch2/BackgroundSelector.mxml
net/systemeD/potlatch2/VectorSourceDialog.mxml [new file with mode: 0644]
net/systemeD/potlatch2/controller/DrawWay.as
net/systemeD/potlatch2/controller/NoSelection.as
net/systemeD/potlatch2/controller/SelectedPOINode.as
net/systemeD/potlatch2/controller/SelectedWay.as
net/systemeD/potlatch2/controller/SelectedWayNode.as
net/systemeD/potlatch2/utils/Importer.as
net/systemeD/potlatch2/utils/ShpImporter.as

index d4c540e..4359791 100644 (file)
--- a/TODO.txt
+++ b/TODO.txt
@@ -9,15 +9,19 @@ Potlatch 2: main outstanding issues
 
 == Core geometry ==
 
-* Delete POIs and ways
-* Merge ways (almost there)
 * Undo/redo
 * Reverse way direction
 
 
+== Vector background layers ==
+
+* Remove existing interaction and add alt-click
+* Import from GPX
+* Import from OSM (is this worth sharing with the XML API stuff?)
+
+
 == Other core ==
 
-* GPS tracks
 * Non-900913 projections
 * Plugin support
 
@@ -38,3 +42,4 @@ Potlatch 2: main outstanding issues
 * Shields
 * Complete MapCSS support
 * Would be useful to be able to 'suspend' redrawing
+* 'Light' version without vectorlayer support etc.
index bfaa057..6417168 100755 (executable)
@@ -120,7 +120,7 @@ package net.systemeD.halcyon {
                // Add object (stroke/fill/roadname) to layer sprite
                
                private function addToLayer(s:DisplayObject,t:uint,sublayer:int=-1):void {
-                       var l:DisplayObject=Map(map).getChildAt(map.WAYSPRITE+5);
+                       var l:DisplayObject=Map(map).paint.getChildAt(map.paint.maxlayer-map.paint.minlayer);
                        var o:DisplayObject=Sprite(l).getChildAt(t);
                        if (sublayer!=-1) { o=Sprite(o).getChildAt(sublayer); }
                        Sprite(o).addChild(s);
index 284fe9c..5ec4b53 100644 (file)
@@ -6,18 +6,21 @@ package net.systemeD.halcyon {
        import flash.text.GridFitType;
        import net.systemeD.halcyon.Globals;
        import net.systemeD.halcyon.styleparser.StyleList;
+       import net.systemeD.halcyon.styleparser.RuleSet;
     import net.systemeD.halcyon.connection.EntityEvent;
 
        public class EntityUI {
 
                protected var sprites:Array=new Array();                // instances in display list
-        protected var listenSprite:Sprite;                             // clickable sprite to receive events
+        protected var listenSprite:Sprite=new Sprite();        // clickable sprite to receive events
                protected var stateClasses:Object=new Object(); // special context-sensitive classes, e.g. :hover
                protected var layer:int=0;                                              // map layer
+               protected var interactive:Boolean=true;                 // does it respond to connection events?
                protected var suspended:Boolean=false;                  // suspend redrawing?
                protected var redrawDue:Boolean=false;                  // redraw called while suspended?
                protected var redrawStyleList:StyleList;                // stylelist to be used when redrawing?
-               public var map:Map;                                                             // reference to parent map
+               public var paint:MapPaint;                                              // reference to parent MapPaint
+               public var ruleset:RuleSet;                                             // reference to ruleset in operation
 
                protected const FILLSPRITE:uint=0;
                protected const CASINGSPRITE:uint=1;
@@ -33,44 +36,43 @@ package net.systemeD.halcyon {
                };
 
                public function EntityUI() {
+                       listenSprite.addEventListener(MouseEvent.CLICK, mouseEvent);
+                       listenSprite.addEventListener(MouseEvent.DOUBLE_CLICK, mouseEvent);
+                       listenSprite.addEventListener(MouseEvent.ROLL_OVER, mouseEvent);
+                       listenSprite.addEventListener(MouseEvent.MOUSE_OUT, mouseEvent);
+                       listenSprite.addEventListener(MouseEvent.MOUSE_DOWN, mouseEvent);
+                       listenSprite.addEventListener(MouseEvent.MOUSE_UP, mouseEvent);
+                       listenSprite.addEventListener(MouseEvent.MOUSE_MOVE, mouseEvent);
                }
 
                // Add object (stroke/fill/roadname) to layer sprite
                
                protected function addToLayer(s:DisplayObject,t:uint,sublayer:int=-1):void {
-                       var l:DisplayObject=Map(map).getChildAt(map.WAYSPRITE+layer);
+                       var l:DisplayObject=paint.getChildAt(layer-paint.minlayer);
                        var o:DisplayObject=Sprite(l).getChildAt(t);
                        if (sublayer!=-1) { o=Sprite(o).getChildAt(sublayer); }
                        Sprite(o).addChild(s);
                        sprites.push(s);
             if ( s is Sprite ) {
-                Sprite(s).mouseEnabled = false;
                 Sprite(s).mouseChildren = false;
+                Sprite(s).mouseEnabled = false;
             }
                }
-               
+
+
                public function removeSprites():void {
                        while (sprites.length>0) {
                                var d:DisplayObject=sprites.pop();
                                if (d.parent) { d.parent.removeChild(d); }
                        }
-                       listenSprite=null;
+                       listenSprite.hitArea=null;
                }
 
-               protected function createListenSprite(hitzone:Sprite):void {
-            if ( listenSprite == null ) {
-                listenSprite = new Sprite();
-                listenSprite.addEventListener(MouseEvent.CLICK, mouseEvent);
-                listenSprite.addEventListener(MouseEvent.DOUBLE_CLICK, mouseEvent);
-                listenSprite.addEventListener(MouseEvent.MOUSE_OVER, mouseEvent);
-                listenSprite.addEventListener(MouseEvent.MOUSE_OUT, mouseEvent);
-                listenSprite.addEventListener(MouseEvent.MOUSE_DOWN, mouseEvent);
-                listenSprite.addEventListener(MouseEvent.MOUSE_UP, mouseEvent);
-                listenSprite.addEventListener(MouseEvent.MOUSE_MOVE, mouseEvent);
-            }
+               protected function setListenSprite(hitzone:Sprite):void {
+                       if (!listenSprite.parent) { addToLayer(listenSprite, CLICKSPRITE); }
             listenSprite.hitArea = hitzone;
-            addToLayer(listenSprite, CLICKSPRITE);
             listenSprite.buttonMode = true;
+            listenSprite.mouseChildren = true;
             listenSprite.mouseEnabled = true;
                }
 
index 58e93be..1c10e50 100755 (executable)
@@ -16,8 +16,9 @@ package net.systemeD.halcyon {
     import net.systemeD.halcyon.connection.*;
     import net.systemeD.halcyon.connection.EntityEvent;
        import net.systemeD.halcyon.styleparser.*;
+       import net.systemeD.halcyon.vectorlayers.*;
        import net.systemeD.halcyon.Globals;
-       
+
 //     for experimental export function:
 //     import flash.net.FileReference;
 //     import com.adobe.images.JPGEncoder;
@@ -29,12 +30,8 @@ package net.systemeD.halcyon {
                public const MINSCALE:uint=13;                                  // don't zoom out past this
                public const MAXSCALE:uint=19;                                  // don't zoom in past this
 
-               public var ruleset:RuleSet;                                             // rules
-               
-               public var ways:Object=new Object();                    // geodata
-               public var nodes:Object=new Object();                   //  |
-               public var pois:Object=new Object();                    //  |
-               public var relations:Object=new Object();               //  |
+               public var paint:MapPaint;                                              // sprite for ways and (POI/tagged) nodes in core layer
+               public var vectorbg:Sprite;                                             // sprite for vector background layers
 
                public var scale:uint=14;                                               // map scale
                public var scalefactor:Number=MASTERSCALE;              // current scaling factor for lon/latp
@@ -74,16 +71,17 @@ package net.systemeD.halcyon {
                public const NOT_MOVED:uint=1;                                  //  |
                public const DRAGGING:uint=2;                                   //  |
                
-               public var initparams:Object;                                   // object containing 
+               public var initparams:Object;                                   // object containing HTML page parameters
 
                public var backdrop:Object;                                             // reference to backdrop sprite
                public var tileset:TileSet;                                             // 900913 tile background
                public var showall:Boolean=true;                                // show all objects, even if unstyled?
                
                public var connection:Connection;                               // server connection
+               public var vectorlayers:Array=[];                               // VectorLayer objects 
 
                public const TILESPRITE:uint=0;
-               public const GPSSPRITE:uint=1;
+               public const VECTORSPRITE:uint=1;
                public const WAYSPRITE:uint=2;
                public const NAMESPRITE:uint=13;
                
@@ -91,6 +89,7 @@ package net.systemeD.halcyon {
                // Map constructor function
 
         public function Map(initparams:Object) {
+
                        this.initparams=initparams;
                        connection = Connection.getConnection(initparams);
             connection.addEventListener(Connection.NEW_WAY, newWayCreated);
@@ -100,50 +99,6 @@ package net.systemeD.halcyon {
                        addEventListener(Event.ENTER_FRAME, everyFrame);
         }
 
-               // Set up layering
-               // [layer][3]                   - names
-               // [layer][2][sublayer] - stroke
-               // [layer][1]                   - casing
-               // [layer][0]                   - fill
-
-               private function createSprites():void {
-                       tileset=new TileSet(this);                                      // 0 - 900913 background
-                       addChild(tileset);                                                      //      |
-                       addChild(new Sprite());                                         // 1 - GPS
-
-                       for (var l:int=0; l<13; l++) {                          // 11 layers (12 is +5, 2 is -5)
-                               var s:Sprite = getHitSprite();          //  |
-                               s.addChild(getPaintSprite());                   //      | 0 fill
-                               s.addChild(getPaintSprite());                   //      | 1 casing
-                               var t:Sprite = getPaintSprite();                //  | 2 stroke
-                               for (var j:int=0; j<11; j++) {                  //      |  | ten sublayers
-                                       t.addChild(getPaintSprite());           //  |  |  |
-                               }                                                                               //  |  |  |
-                               s.addChild(t);                                                  //  |  |
-                               s.addChild(getPaintSprite());                   //      | 3 names
-                               s.addChild(getPaintSprite());                   //      | 4 nodes
-                               s.addChild(getHitSprite());                         //  | 5 entity hit tests
-                               addChild(s);                                                    //  |
-                       }
-                       addChild(getPaintSprite());                             // 13 - name sprite
-               }
-               
-               private function removeSprites():void {
-                       while (numChildren) { removeChildAt(0); }
-               }
-
-        private function getPaintSprite():Sprite {
-            var s:Sprite = new Sprite();
-            s.mouseEnabled = false;
-            s.mouseChildren = false;
-            return s;
-        }
-
-        private function getHitSprite():Sprite {
-            var s:Sprite = new Sprite();
-            return s;
-        }
-
                public function gotEnvironment(r:Object):void {
                        var loader:Loader = new Loader();
                        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, gotFont);
@@ -172,13 +127,21 @@ package net.systemeD.halcyon {
                // Initialise map at a given lat/lon
 
         public function init(startlat:Number,startlon:Number,startscale:uint=0,style:String=null,tileurl:String=''):void {
-                       removeSprites();
-                       createSprites();
+                       while (numChildren) { removeChildAt(0); }
+
+                       tileset=new TileSet(this);                                      // 0 - 900913 background
+                       addChild(tileset);                                                      //   |
                        tileset.init(tileurl);
 
+                       vectorbg = new Sprite();                                        // 1 - vector background layers
+                       addChild(vectorbg);                                                     //   |
+
+                       paint = new MapPaint(this,-5,5);                        // 2 - core paint object
+                       addChild(paint);                                                        //   |
+
                        if (style) {
-                               ruleset=new RuleSet(this,redrawPOIs);
-                               ruleset.loadFromCSS(style);
+                               paint.ruleset=new RuleSet(MINSCALE,MAXSCALE,redraw,redrawPOIs);
+                               paint.ruleset.loadFromCSS(style);
                        }
                        if (startscale>0) { scale=startscale; }
 
@@ -202,8 +165,6 @@ package net.systemeD.halcyon {
                        edge_l=coord2lon(-x          );
                        edge_r=coord2lon(-x+mapwidth );
                        setCentre();
-//                     addDebug("Lon "+edge_l+"-"+edge_r);
-//                     addDebug("Lat "+edge_b+"-"+edge_t);
 
                        tileset.update();
                }
@@ -275,20 +236,20 @@ package net.systemeD.halcyon {
         private function newWayCreated(event:EntityEvent):void {
             var way:Way = event.entity as Way;
                        if (!way.loaded) { return; }
-            ways[way.id] = new WayUI(way, this);
+                       paint.createWayUI(way);
         }
 
         private function newPOICreated(event:EntityEvent):void {
             var node:Node = event.entity as Node;
-            pois[node.id] = new NodeUI(node, this);
-                       pois[node.id].redraw();
+                       var nodeui:NodeUI=paint.createNodeUI(node);
+                       nodeui.redraw();
         }
 
         public function setHighlight(entity:Entity, settings:Object):void {
                        var stateType:String;
                        var ui:EntityUI=null;
-                       if      ( entity is Way  ) { ui = ways[entity.id]; }
-                       else if ( entity is Node ) { ui = pois[entity.id]; }
+                       if      ( entity is Way  ) { ui = paint.wayuis[entity.id]; }
+                       else if ( entity is Node ) { ui = paint.nodeuis[entity.id]; }
                        if (ui==null) { return; }
                        for (stateType in settings) {
                                ui.setHighlight(stateType, settings[stateType]);
@@ -313,14 +274,14 @@ package net.systemeD.halcyon {
                // Redraw all items, zoom in and out
                
                public function redraw():void {
-                       for each (var w:WayUI in ways) { w.recalculate(); w.redraw(); }
-                       for each (var p:NodeUI in pois) { p.redraw(); }
+                       paint.redraw();
+                       for each (var v:VectorLayer in vectorlayers) { v.paint.redraw(); }
                }
-
-               public function redrawPOIs():void {
-                       for each (var p:NodeUI in pois) { p.redraw(); }
+               public function redrawPOIs():void { 
+                       paint.redrawPOIs();
+                       for each (var v:VectorLayer in vectorlayers) { v.paint.redrawPOIs(); }
                }
-
+               
                public function zoomIn():void {
                        if (scale==MAXSCALE) { return; }
                        changeScale(scale+1);
@@ -347,8 +308,8 @@ package net.systemeD.halcyon {
                
                public function setStyle(style:String):void {
                        if (style) {
-                               ruleset=new RuleSet(this,redrawPOIs);
-                               ruleset.loadFromCSS(style);
+                               paint.ruleset=new RuleSet(MINSCALE,MAXSCALE,redraw,redrawPOIs);
+                               paint.ruleset.loadFromCSS(style);
                        }
         }
 
@@ -418,13 +379,12 @@ package net.systemeD.halcyon {
                // Miscellaneous events
                
                public function keyUpHandler(event:KeyboardEvent):void {
-// addDebug("pressed "+event.keyCode);
-            if ( !event.ctrlKey ) return;
-                       if (event.keyCode==82) { this.redraw(); }                       // R - redraw
-                       if (event.keyCode==73) { this.zoomIn(); }                       // I - zoom in
-                       if (event.keyCode==79) { this.zoomOut(); }                      // O - zoom out
-                       if (event.keyCode==76) { this.reportPosition(); }       // L - report lat/long
-//                     if (event.keyCode==69) { this.export(); }                       // E - export
+                       if ( !event.ctrlKey ) return;
+                       addDebug("pressed "+event.keyCode);
+                       if (event.keyCode==82) { redraw(); }                    // R - redraw
+                       if (event.keyCode==73) { zoomIn(); }                    // I - zoom in
+                       if (event.keyCode==79) { zoomOut(); }                   // O - zoom out
+                       if (event.keyCode==76) { reportPosition(); }    // L - report lat/long
                }
 
                public function connectionError(err:Object=null): void {
@@ -440,6 +400,6 @@ package net.systemeD.halcyon {
                        Globals.vars.debug.appendText(text+"\n");
                        Globals.vars.debug.scrollV=Globals.vars.debug.maxScrollV;
                }
-               
+
        }
 }
diff --git a/net/systemeD/halcyon/MapPaint.as b/net/systemeD/halcyon/MapPaint.as
new file mode 100644 (file)
index 0000000..c912a44
--- /dev/null
@@ -0,0 +1,110 @@
+package net.systemeD.halcyon {
+
+       import flash.display.Sprite;
+       import flash.display.DisplayObject;
+       import net.systemeD.halcyon.NodeUI;
+       import net.systemeD.halcyon.WayUI;
+       import net.systemeD.halcyon.connection.Node;
+       import net.systemeD.halcyon.connection.Way;
+       import net.systemeD.halcyon.styleparser.RuleSet;
+       import net.systemeD.halcyon.Globals;
+
+    public class MapPaint extends Sprite {
+
+               public var map:Map;
+               public var minlayer:int;
+               public var maxlayer:int;
+               public var ruleset:RuleSet;                                             // rules
+               public var wayuis:Object=new Object();                  // sprites for ways and (POI/tagged) nodes
+               public var nodeuis:Object=new Object();                 //  |
+
+               // Set up layering
+               // [layer][3]                   - names
+               // [layer][2][sublayer] - stroke
+               // [layer][1]                   - casing
+               // [layer][0]                   - fill
+
+               public function MapPaint(map:Map,minlayer:int,maxlayer:int) {
+                       this.map=map;
+                       this.minlayer=minlayer;
+                       this.maxlayer=maxlayer;
+
+                       for (var l:int=minlayer; l<=maxlayer; l++) {    // each layer (10 is +5, 0 is -5)
+                               var s:Sprite = getHitSprite();                  //  |
+                               s.addChild(getPaintSprite());                           //      | 0 fill
+                               s.addChild(getPaintSprite());                           //      | 1 casing
+                               var t:Sprite = getPaintSprite();                        //  | 2 stroke
+                               for (var j:int=0; j<11; j++) {                          //      |  | ten sublayers
+                                       t.addChild(getPaintSprite());                   //  |  |  |
+                               }                                                                                       //  |  |  |
+                               s.addChild(t);                                                          //  |  |
+                               s.addChild(getPaintSprite());                           //      | 3 names
+                               s.addChild(getPaintSprite());                           //      | 4 nodes
+                               s.addChild(getHitSprite());                                 //  | 5 entity hit tests
+                               addChild(s);                                                            //  |
+                       }
+                       addChild(getPaintSprite());                                     // name sprite
+               }
+               
+               public function get ready():Boolean {
+                       if (!ruleset) { return false; }
+                       if (!ruleset.loaded) { return false; }
+                       return true;
+               }
+
+/*             public function addToLayer(s:DisplayObject, layer:int, t:uint, sublayer:int=-1) {
+                       var l:DisplayObject=getChildAt(layer-minlayer);
+                       var o:DisplayObject=Sprite(l).getChildAt(t);
+                       if (sublayer!=-1) { o=Sprite(o).getChildAt(sublayer); }
+                       Sprite(o).addChild(s);
+                       sprites.push(s);
+            if ( s is Sprite ) {
+                Sprite(s).mouseEnabled = false;
+                Sprite(s).mouseChildren = false;
+            }
+               }
+*/
+
+               public function createWayUI(way:Way):WayUI {
+                       wayuis[way.id]=new WayUI(way,this,false);
+                       return wayuis[way.id];
+               }
+
+               public function createNodeUI(node:Node):NodeUI {
+                       nodeuis[node.id]=new NodeUI(node,this,0,false);
+                       return nodeuis[node.id];
+               }
+
+               public function deleteWayUI(way:Way):void {
+                       wayuis[way.id].removeSprites();
+                       delete wayuis[way.id];
+               }
+
+               public function deleteNodeUI(node:Node):void {
+                       nodeuis[node.id].removeSprites();
+                       delete nodeuis[node.id];
+               }
+
+        private function getPaintSprite():Sprite {
+            var s:Sprite = new Sprite();
+            s.mouseEnabled = false;
+            s.mouseChildren = false;
+            return s;
+        }
+
+        private function getHitSprite():Sprite {
+            var s:Sprite = new Sprite();
+            return s;
+        }
+
+               public function redraw():void {
+                       for each (var w:WayUI in wayuis) { w.recalculate(); w.redraw(); }
+                       for each (var p:NodeUI in nodeuis) { p.redraw(); }
+               }
+
+               public function redrawPOIs():void {
+                       for each (var p:NodeUI in nodeuis) { p.redraw(); }
+               }
+
+       }
+}
index 1e11226..fc0cb99 100644 (file)
@@ -21,11 +21,12 @@ package net.systemeD.halcyon {
                private var heading:Number=0;                           // heading within way
                private var rotation:Number=0;                          // rotation applied to this POI
 
-               public function NodeUI(node:Node, map:Map, heading:Number=0) {
+               public function NodeUI(node:Node, paint:MapPaint, heading:Number=0, interactive:Boolean=true) {
                        super();
-                       this.map = map;
                        this.node = node;
+                       this.paint = paint;
                        this.heading = heading;
+                       this.interactive = interactive;
                        node.addEventListener(Connection.NODE_MOVED, nodeMoved);
                        node.addEventListener(Connection.NODE_DELETED, nodeDeleted);
                        node.addEventListener(Connection.SUSPEND_REDRAW, suspendRedraw);
@@ -41,10 +42,13 @@ package net.systemeD.halcyon {
                }
                
                override public function doRedraw(sl:StyleList):Boolean {
+                       if (!paint.ready) { return false; }
+                       if (node.deleted) { return false; }
+
                        var tags:Object = node.getTagsCopy();
                        tags=applyStateClasses(tags);
                        if (!node.hasParentWays) { tags[':poi']='yes'; }
-                       if (!sl) { sl=map.ruleset.getStyles(this.node,tags); }
+                       if (!sl) { sl=paint.ruleset.getStyles(this.node,tags); }
 
                        var inWay:Boolean=node.hasParentWays;
                        var hasStyles:Boolean=sl.hasStyles();
@@ -57,7 +61,7 @@ package net.systemeD.halcyon {
                        var r:Boolean=false;    // ** rendered
                        var w:Number;
                        var icon:Sprite;
-                       layer=10;
+                       layer=paint.maxlayer;
                        for (var sublayer:int=10; sublayer>=0; sublayer--) {
 
                                if (sl.pointStyles[sublayer]) {
@@ -86,11 +90,11 @@ package net.systemeD.halcyon {
                                                        updatePosition();
                                                        iconname='_circle';
 
-                                               } else if (map.ruleset.images[s.icon_image]) {
+                                               } else if (paint.ruleset.images[s.icon_image]) {
                                                        // 'load' icon (actually just from library)
                                                        var loader:Loader = new Loader();
                                                        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event):void { loadedIcon(e,sublayer); } );
-                                                       loader.loadBytes(map.ruleset.images[s.icon_image]);
+                                                       loader.loadBytes(paint.ruleset.images[s.icon_image]);
                                                        iconname=s.icon_image;
                                                }
                                        } else {
@@ -109,7 +113,7 @@ package net.systemeD.halcyon {
                                if (a) { 
                                        var name:Sprite=new Sprite();
                                        addToLayer(name,NAMESPRITE);
-                                       t.writeNameLabel(name,a,map.lon2coord(node.lon),map.latp2coord(node.latp));
+                                       t.writeNameLabel(name,a,paint.map.lon2coord(node.lon),paint.map.latp2coord(node.latp));
                                }
                        }
                        return r;
@@ -141,7 +145,7 @@ package net.systemeD.halcyon {
                        hitzone.graphics.drawRect(0,0,w,w);
             addToLayer(hitzone, CLICKSPRITE);
             hitzone.visible = false;
-                       createListenSprite(hitzone);
+                       setListenSprite(hitzone);
                }
 
                private function loadedIcon(event:Event,sublayer:uint):void {
@@ -154,7 +158,7 @@ package net.systemeD.halcyon {
                }
 
         override protected function mouseEvent(event:MouseEvent):void {
-                       map.entityMouseEvent(event, node);
+                       paint.map.entityMouseEvent(event, node);
         }
 
                private function updatePosition():void {
@@ -167,7 +171,7 @@ package net.systemeD.halcyon {
                                var m:Matrix=new Matrix();
                                m.translate(-d.width/2,-d.height/2);
                                m.rotate(rotation);
-                               m.translate(map.lon2coord(node.lon),map.latp2coord(node.latp));
+                               m.translate(paint.map.lon2coord(node.lon),paint.map.latp2coord(node.latp));
                                d.transform.matrix=m;
                        }
                }
index c1a7845..34cf8cf 100644 (file)
@@ -16,9 +16,9 @@ package net.systemeD.halcyon {
                        this.graphics=graphics;
                        this.style=style;
                        
-                       if (wayui.map.ruleset.images[style.fill_image]) {
+                       if (wayui.paint.ruleset.images[style.fill_image]) {
                                loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadedFill);
-                               loader.loadBytes(wayui.map.ruleset.images[style.fill_image]);
+                               loader.loadBytes(wayui.paint.ruleset.images[style.fill_image]);
                        }
                }
                
index 597de3f..59b8a41 100755 (executable)
@@ -24,10 +24,12 @@ package net.systemeD.halcyon {
 
                private const NODESIZE:uint=6;
 
-               public function WayUI(way:Way, map:Map) {
+               public function WayUI(way:Way, paint:MapPaint, interactive:Boolean=true) {
                        super();
                        this.way = way;
-                       this.map = map;
+                       this.paint = paint;
+                       this.ruleset = ruleset;
+                       this.interactive = interactive;
             init();
             way.addEventListener(Connection.TAG_CHANGED, wayTagChanged);
             way.addEventListener(Connection.WAY_NODE_ADDED, wayNodeAdded);
@@ -115,7 +117,7 @@ package net.systemeD.halcyon {
 
                                // length and area
                                if ( i>0 ) { pathlength += Math.sqrt( Math.pow(lon-lx,2)+Math.pow(latp-ly,2) ); }
-                               sc = (lx*latp-lon*ly)*map.scalefactor;
+                               sc = (lx*latp-lon*ly)*paint.map.scalefactor;
                                cx += (lx+lon)*sc;
                                cy += (ly+latp)*sc;
                                patharea += sc;
@@ -127,11 +129,11 @@ package net.systemeD.halcyon {
                        }
                        heading[way.length-1]=heading[way.length-2];
 
-                       pathlength*=map.scalefactor;
+                       pathlength*=paint.map.scalefactor;
                        patharea/=2;
                        if (patharea!=0 && way.isArea()) {
-                               centroid_x=map.lon2coord(cx/patharea/6);
-                               centroid_y=map.latp2coord(cy/patharea/6);
+                               centroid_x=paint.map.lon2coord(cx/patharea/6);
+                               centroid_y=paint.map.latp2coord(cy/patharea/6);
                        } else if (pathlength>0) {
                                var c:Array=pointAt(0.5);
                                centroid_x=c[0];
@@ -145,6 +147,7 @@ package net.systemeD.halcyon {
                override public function doRedraw(sl:StyleList):Boolean {
                        removeSprites();
                        if (way.length==0) { return false; }
+                       if (!paint.ready) { return false; }
 
             // Copy tags object, and add states
             var tags:Object = way.getTagsCopy();
@@ -152,19 +155,18 @@ package net.systemeD.halcyon {
                        if (way.isArea()) { tags[':area']='yes'; }
 
                        // Which layer?
-                       layer=5;
-                       if ( tags['layer'] )
-                layer=Math.min(Math.max(tags['layer']+5,-5),5)+5;
+                       layer=0;
+                       if (tags['layer']) { layer=Math.min(Math.max(tags['layer'],paint.minlayer),paint.maxlayer); }
 
                        // Iterate through each sublayer, drawing any styles on that layer
-                       if (!sl) { sl=map.ruleset.getStyles(this.way, tags); }
+                       if (!sl) { sl=paint.ruleset.getStyles(this.way, tags); }
                        var drawn:Boolean;
                        for (var sublayer:int=10; sublayer>=0; sublayer--) {
                                if (sl.shapeStyles[sublayer]) {
                                        var s:ShapeStyle=sl.shapeStyles[sublayer];
                                        var stroke:Shape, fill:Shape, casing:Shape, roadname:Sprite;
-                                       var x0:Number=map.lon2coord(way.getNode(0).lon);
-                                       var y0:Number=map.latp2coord(way.getNode(0).latp);
+                                       var x0:Number=paint.map.lon2coord(way.getNode(0).lon);
+                                       var y0:Number=paint.map.latp2coord(way.getNode(0).latp);
 
                                        // Stroke
                                        if (s.width)  {
@@ -233,15 +235,15 @@ package net.systemeD.halcyon {
                                if (stateClasses["showNodesHover"]) { nodetags[':hoverway']='yes'; }
                                if (node.id==nodeSelected) { nodetags[':selected']='yes'; }
                                if (node.numParentWays>1) { nodetags[':junction']='yes'; }
-                               sl=map.ruleset.getStyles(node,nodetags);
+                               sl=paint.ruleset.getStyles(node,nodetags);
                                if (sl.hasStyles()) {
-                                       if (!map.pois[node.id]) {
-                                               map.pois[node.id]=new NodeUI(node,map,r);
+                                       if (!paint.nodeuis[node.id]) {
+                                               paint.nodeuis[node.id]=new NodeUI(node,paint,r);
                                        }
-                                       map.pois[node.id].redraw(sl);
-                               } else if (map.pois[node.id]) {
-                                       map.pois[node.id].removeSprites();
-                                       delete map.pois[node.id];
+                                       paint.nodeuis[node.id].redraw(sl);
+                               } else if (paint.nodeuis[node.id]) {
+                                       paint.nodeuis[node.id].removeSprites();
+                                       delete paint.nodeuis[node.id];
                                }
                        }
                        if (!drawn) { return false; }
@@ -252,7 +254,7 @@ package net.systemeD.halcyon {
             solidLine(hitzone.graphics);
             addToLayer(hitzone, CLICKSPRITE);
             hitzone.visible = false;
-                       createListenSprite(hitzone);
+                       setListenSprite(hitzone);
 
                        return true;
                }
@@ -264,10 +266,10 @@ package net.systemeD.halcyon {
                
                public function solidLine(g:Graphics):void {
             var node:Node = way.getNode(0);
-                       g.moveTo(map.lon2coord(node.lon), map.latp2coord(node.latp));
+                       g.moveTo(paint.map.lon2coord(node.lon), paint.map.latp2coord(node.latp));
                        for (var i:uint = 1; i < way.length; i++) {
                 node = way.getNode(i);
-                               g.lineTo(map.lon2coord(node.lon), map.latp2coord(node.latp));
+                               g.lineTo(paint.map.lon2coord(node.lon), paint.map.latp2coord(node.latp));
                        }
                }
 
@@ -282,7 +284,7 @@ package net.systemeD.halcyon {
 
             var node:Node = way.getNode(0);
             var nextNode:Node = way.getNode(0);
-                       g.moveTo(map.lon2coord(node.lon), map.latp2coord(node.latp));
+                       g.moveTo(paint.map.lon2coord(node.lon), paint.map.latp2coord(node.latp));
                        while (i < way.length-1 || segleft>0) {
                                if (dashleft<=0) {      // should be ==0
                                        if (dc.length==0) { dc=dashes.slice(0); }
@@ -292,10 +294,10 @@ package net.systemeD.halcyon {
                                if (segleft<=0) {       // should be ==0
                     node = way.getNode(i);
                     nextNode = way.getNode(i+1);
-                                       curx=map.lon2coord(node.lon);
-                    dx=map.lon2coord(nextNode.lon)-curx;
-                                       cury=map.latp2coord(node.latp);
-                    dy=map.latp2coord(nextNode.latp)-cury;
+                                       curx=paint.map.lon2coord(node.lon);
+                    dx=paint.map.lon2coord(nextNode.lon)-curx;
+                                       cury=paint.map.latp2coord(node.latp);
+                    dy=paint.map.latp2coord(nextNode.latp)-cury;
                                        a=Math.atan2(dy,dx); xc=Math.cos(a); yc=Math.sin(a);
                                        segleft=Math.sqrt(dx*dx+dy*dy);
                                        i++;
@@ -331,12 +333,12 @@ package net.systemeD.halcyon {
                        var curlen:Number = 0;
                        var dx:Number, dy:Number, seglen:Number;
                        for (var i:int = 1; i < way.length; i++){
-                               dx=map.lon2coord(way.getNode(i).lon)-map.lon2coord(way.getNode(i-1).lon);
-                               dy=map.latp2coord(way.getNode(i).latp)-map.latp2coord(way.getNode(i-1).latp);
+                               dx=paint.map.lon2coord(way.getNode(i).lon)-paint.map.lon2coord(way.getNode(i-1).lon);
+                               dy=paint.map.latp2coord(way.getNode(i).latp)-paint.map.latp2coord(way.getNode(i-1).latp);
                                seglen=Math.sqrt(dx*dx+dy*dy);
                                if (totallen > curlen+seglen) { curlen+=seglen; continue; }
-                               return new Array(map.lon2coord(way.getNode(i-1).lon)+(totallen-curlen)/seglen*dx,
-                                                                map.latp2coord(way.getNode(i-1).latp)+(totallen-curlen)/seglen*dy,
+                               return new Array(paint.map.lon2coord(way.getNode(i-1).lon)+(totallen-curlen)/seglen*dx,
+                                                                paint.map.latp2coord(way.getNode(i-1).latp)+(totallen-curlen)/seglen*dy,
                                                                 Math.atan2(dy,dx));
                        }
                        return new Array(0, 0, 0);
@@ -407,8 +409,8 @@ package net.systemeD.halcyon {
                public function getNodeAt(x:Number, y:Number):Node {
                        for (var i:uint = 0; i < way.length; i++) {
                 var node:Node = way.getNode(i);
-                var nodeX:Number = map.lon2coord(node.lon);
-                var nodeY:Number = map.latp2coord(node.latp);
+                var nodeX:Number = paint.map.lon2coord(node.lon);
+                var nodeY:Number = paint.map.latp2coord(node.latp);
                 if ( nodeX >= x-NODESIZE && nodeX <= x+NODESIZE &&
                      nodeY >= y-NODESIZE && nodeY <= y+NODESIZE )
                     return node;
@@ -417,7 +419,7 @@ package net.systemeD.halcyon {
                }
 
         override protected function mouseEvent(event:MouseEvent):void {
-                       map.entityMouseEvent(event, way);
+                       paint.map.entityMouseEvent(event, way);
         }
 
        }
index 14d48a1..0941d50 100755 (executable)
@@ -4,6 +4,7 @@ package net.systemeD.halcyon.connection {
 
     import flash.events.EventDispatcher;
     import flash.events.Event;
+       import net.systemeD.halcyon.Globals;
 
        public class Connection extends EventDispatcher {
 
@@ -128,7 +129,7 @@ package net.systemeD.halcyon.connection {
             }
         }
 
-        protected function unregisterPOI(node:Node):void {
+        public function unregisterPOI(node:Node):void {
             var index:uint = pois.indexOf(node);
             if ( index >= 0 ) {
                 pois.splice(index,1);
index 1d2feb4..8039cb7 100644 (file)
@@ -11,7 +11,7 @@ package net.systemeD.halcyon.connection {
                private var _loaded:Boolean = true;
                private var parents:Dictionary = new Dictionary();
                private var locked:Boolean = false;
-               protected var deleted:Boolean = false;
+               public var deleted:Boolean = false;
 
         public function Entity(id:Number, version:uint, tags:Object, loaded:Boolean) {
             this._id = id;
index 5039c08..918012c 100755 (executable)
@@ -9,12 +9,12 @@ package net.systemeD.halcyon.styleparser {
        import flash.events.*;
        import flash.net.*;
        import net.systemeD.halcyon.Globals;
-       import net.systemeD.halcyon.Map;
 
        // ** also needs to support @import rules
 
        public class MapCSS {
-               private var map:Map;
+               private var minscale:uint;
+               private var maxscale:uint;
                private var choosers:Array;
 
                private static const WHITESPACE:RegExp  =/^ \s+ /sx;
@@ -33,17 +33,17 @@ package net.systemeD.halcyon.styleparser {
                private static const ZOOM_MAX:RegExp    =/^      \-(\d+) $/sx;
                private static const ZOOM_SINGLE:RegExp =/^        (\d+) $/sx;
 
-                private static const CONDITION_TRUE:RegExp      =/^ \s* ([:\w]+) \s* = \s* yes \s*  $/isx;
-                private static const CONDITION_FALSE:RegExp     =/^ \s* ([:\w]+) \s* = \s* no  \s*  $/isx;
-                private static const CONDITION_SET:RegExp       =/^ \s* ([:\w]+) \s* $/sx;
-                private static const CONDITION_UNSET:RegExp     =/^ \s* !([:\w]+) \s* $/sx;
-                private static const CONDITION_EQ:RegExp        =/^ \s* ([:\w]+) \s* =  \s* (.+) \s* $/sx;
-                private static const CONDITION_NE:RegExp        =/^ \s* ([:\w]+) \s* != \s* (.+) \s* $/sx;
-                private static const CONDITION_GT:RegExp        =/^ \s* ([:\w]+) \s* >  \s* (.+) \s* $/sx;
-                private static const CONDITION_GE:RegExp        =/^ \s* ([:\w]+) \s* >= \s* (.+) \s* $/sx;
-                private static const CONDITION_LT:RegExp        =/^ \s* ([:\w]+) \s* <  \s* (.+) \s* $/sx;
-                private static const CONDITION_LE:RegExp        =/^ \s* ([:\w]+) \s* <= \s* (.+) \s* $/sx;
-                private static const CONDITION_REGEX:RegExp     =/^ \s* ([:\w]+) \s* =~\/ \s* (.+) \/ \s* $/sx;
+               private static const CONDITION_TRUE:RegExp      =/^ \s* ([:\w]+) \s* = \s* yes \s*  $/isx;
+               private static const CONDITION_FALSE:RegExp     =/^ \s* ([:\w]+) \s* = \s* no  \s*  $/isx;
+               private static const CONDITION_SET:RegExp       =/^ \s* ([:\w]+) \s* $/sx;
+               private static const CONDITION_UNSET:RegExp     =/^ \s* !([:\w]+) \s* $/sx;
+               private static const CONDITION_EQ:RegExp        =/^ \s* ([:\w]+) \s* =  \s* (.+) \s* $/sx;
+               private static const CONDITION_NE:RegExp        =/^ \s* ([:\w]+) \s* != \s* (.+) \s* $/sx;
+               private static const CONDITION_GT:RegExp        =/^ \s* ([:\w]+) \s* >  \s* (.+) \s* $/sx;
+               private static const CONDITION_GE:RegExp        =/^ \s* ([:\w]+) \s* >= \s* (.+) \s* $/sx;
+               private static const CONDITION_LT:RegExp        =/^ \s* ([:\w]+) \s* <  \s* (.+) \s* $/sx;
+               private static const CONDITION_LE:RegExp        =/^ \s* ([:\w]+) \s* <= \s* (.+) \s* $/sx;
+               private static const CONDITION_REGEX:RegExp     =/^ \s* ([:\w]+) \s* =~\/ \s* (.+) \/ \s* $/sx;
 
                private static const ASSIGNMENT_EVAL:RegExp     =/^ \s* (\S+) \s* \:      \s* eval \s* \( \s* ' (.+?) ' \s* \) \s* $/isx;
                private static const ASSIGNMENT:RegExp          =/^ \s* (\S+) \s* \:      \s*          (.+?) \s*                   $/sx;
@@ -210,8 +210,9 @@ package net.systemeD.halcyon.styleparser {
                        yellowgreen:0x9acd32 };
 
 
-               public function MapCSS(m:Map) {
-                       map=m;
+               public function MapCSS(mins:uint,maxs:uint) {
+                       minscale=mins;
+                       maxscale=maxs;
                }
                
                public function parse(css:String):Array {
@@ -371,8 +372,8 @@ package net.systemeD.halcyon.styleparser {
                private function parseZoom(s:String):Array {
                        var o:Object=new Object();
                        if ((o=ZOOM_MINMAX.exec(s))) { return [o[1],o[2]]; }
-                       else if ((o=ZOOM_MIN.exec(s))) { return [o[1],map.MAXSCALE]; }
-                       else if ((o=ZOOM_MAX.exec(s))) { return [map.MINSCALE,o[1]]; }
+                       else if ((o=ZOOM_MIN.exec(s))) { return [o[1],maxscale]; }
+                       else if ((o=ZOOM_MAX.exec(s))) { return [minscale,o[1]]; }
                        else if ((o=ZOOM_SINGLE.exec(s))) { return [o[1],o[1]]; }
                        return null;
                }
index 1840e2f..bdc1586 100644 (file)
@@ -2,7 +2,6 @@ package net.systemeD.halcyon.styleparser {
 
        import flash.events.*;
        import flash.net.*;
-       import net.systemeD.halcyon.Map;
        import net.systemeD.halcyon.ExtendedLoader;
        import net.systemeD.halcyon.ExtendedURLLoader;
     import net.systemeD.halcyon.connection.Entity;
@@ -13,17 +12,22 @@ package net.systemeD.halcyon.styleparser {
        
        public class RuleSet {
 
-               private var map:Map;
+               private var minscale:uint;
+               private var maxscale:uint;
+               public var loaded:Boolean=false;                        // has it loaded yet?
                public var choosers:Array=new Array();          // list of StyleChoosers
                public var images:Object=new Object();          // loaded images
                public var imageWidths:Object=new Object();     // width of each bitmap image
+               private var redrawCallback:Function=null;       // function to call when CSS loaded
                private var iconCallback:Function=null;         // function to call when all icons loaded
                private var iconsToLoad:uint=0;                         // number of icons left to load (fire callback when ==0)
 
                // variables for name, author etc.
 
-               public function RuleSet(m:Map,iconLoadedCallback:Function=null):void {
-                       map = m;
+               public function RuleSet(mins:uint,maxs:uint,redrawCall:Function=null,iconLoadedCallback:Function=null):void {
+                       minscale = mins;
+                       maxscale = maxs;
+                       redrawCallback = redrawCall;
                        iconCallback = iconLoadedCallback;
                }
 
@@ -41,31 +45,33 @@ package net.systemeD.halcyon.styleparser {
                // Loading stylesheet
 
                public function loadFromCSS(str:String):void {
-                       if (str.match(/[\s\n\r\t]/)!=null) { parseCSS(str); return; }
+                       if (str.match(/[\s\n\r\t]/)!=null) { parseCSS(str); redrawCallback(); return; }
 
                        var request:URLRequest=new URLRequest(str);
                        var loader:URLLoader=new URLLoader();
 
                        request.method=URLRequestMethod.GET;
                        loader.dataFormat = URLLoaderDataFormat.TEXT;
-                       loader.addEventListener(Event.COMPLETE,                                         loadedCSS,                              false, 0, true);
-                       loader.addEventListener(HTTPStatusEvent.HTTP_STATUS,            httpStatusHandler,              false, 0, true);
-                       loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,      securityErrorHandler,   false, 0, true);
-                       loader.addEventListener(IOErrorEvent.IO_ERROR,                          ioErrorHandler,                 false, 0, true);
+                       loader.addEventListener(Event.COMPLETE,                                         doRedrawCallback);
+                       loader.addEventListener(HTTPStatusEvent.HTTP_STATUS,            httpStatusHandler);
+                       loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,      securityErrorHandler);
+                       loader.addEventListener(IOErrorEvent.IO_ERROR,                          ioErrorHandler);
                        loader.load(request);
                }
 
-               private function loadedCSS(event:Event):void {
-                       parseCSS(event.target.data);
-               }
-               
                private function parseCSS(str:String):void {
-                       var css:MapCSS=new MapCSS(map);
+                       var css:MapCSS=new MapCSS(minscale,maxscale);
                        choosers=css.parse(str);
 //                     Inspector.getInstance().show();
 //                     Inspector.getInstance().shelf('Choosers', choosers);
                        loadImages();
-                       map.redraw();
+//                     map.redraw();
+               }
+
+               private function doRedrawCallback(e:Event):void {
+                       parseCSS(e.target.data);
+                       loaded=true;
+                       redrawCallback();
                }
 
 
@@ -106,7 +112,7 @@ package net.systemeD.halcyon.styleparser {
                        var loader:ExtendedLoader = new ExtendedLoader();
                        loader.info['filename']=fn;
                        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, measureWidth);
-                       loader.loadBytes(map.ruleset.images[fn]);
+                       loader.loadBytes(images[fn]);
                }
                
                private function measureWidth(event:Event):void {
diff --git a/net/systemeD/halcyon/vectorlayers/CustomVectorLayer.as b/net/systemeD/halcyon/vectorlayers/CustomVectorLayer.as
new file mode 100644 (file)
index 0000000..fe9bb0d
--- /dev/null
@@ -0,0 +1,21 @@
+package net.systemeD.halcyon.vectorlayers {
+
+       import net.systemeD.halcyon.Map;
+       import net.systemeD.halcyon.NodeUI;
+       import net.systemeD.halcyon.WayUI;
+       import net.systemeD.halcyon.connection.Way;
+       import net.systemeD.halcyon.connection.Node;
+       import net.systemeD.halcyon.connection.Entity;
+       import net.systemeD.halcyon.styleparser.*;
+
+       // A CustomVectorLayer can be fully styled with Halcyon rules.
+
+       public class CustomVectorLayer extends VectorLayer {
+
+               public function CustomVectorLayer(m:Map,style:String) {
+                       super(m);
+                       paint.ruleset=new RuleSet(m.MINSCALE,m.MAXSCALE,paint.redraw);
+                       paint.ruleset.loadFromCSS(style);
+               }
+       }
+}
diff --git a/net/systemeD/halcyon/vectorlayers/SimpleVectorLayer.as b/net/systemeD/halcyon/vectorlayers/SimpleVectorLayer.as
new file mode 100644 (file)
index 0000000..d2976ff
--- /dev/null
@@ -0,0 +1,9 @@
+package net.systemeD.halcyon.vectorlayers {
+
+       // A CustomVectorLayer has a simpler, lines-only appearance - suitable for
+       // large quantities of data such as GPX traces.
+
+       public class SimpleVectorLayer extends VectorLayer {
+               // todo
+       }
+}
diff --git a/net/systemeD/halcyon/vectorlayers/VectorLayer.as b/net/systemeD/halcyon/vectorlayers/VectorLayer.as
new file mode 100644 (file)
index 0000000..b9e2d18
--- /dev/null
@@ -0,0 +1,41 @@
+package net.systemeD.halcyon.vectorlayers {
+
+       import net.systemeD.halcyon.Map;
+       import net.systemeD.halcyon.MapPaint;
+       import net.systemeD.halcyon.connection.Node;
+       import net.systemeD.halcyon.connection.Way;
+       import net.systemeD.halcyon.connection.Relation;
+
+       public class VectorLayer extends Object {
+
+               public var map:Map;
+               public var paint:MapPaint;                                              // sprites
+
+               public var ways:Object=new Object();                    // geodata
+               public var nodes:Object=new Object();                   //  |
+               public var relations:Object=new Object();               //  |
+        private var negativeID:Number = -1;
+
+               public function VectorLayer(m:Map) {
+                       map=m;
+                       paint=new MapPaint(m,0,0);
+               }
+               
+               public function createNode(tags:Object,lat:Number,lon:Number):Node {
+                       var node:Node = new Node(negativeID, 0, tags, true, lat, lon);
+                       nodes[negativeID]=node; negativeID--;
+                       return node;
+               }
+               public function createWay(tags:Object,nodes:Array):Way {
+                       var way:Way = new Way(negativeID, 0, tags, true, nodes.concat());
+                       ways[negativeID]=way; negativeID--;
+                       return way;
+               }
+               public function createRelation(tags:Object,members:Array):Relation {
+            var relation:Relation = new Relation(negativeID, 0, tags, true, members.concat());
+                       relations[negativeID]=relation; negativeID--;
+            return relation;
+               }
+
+       }
+}
index 0e6c1a0..f435afd 100644 (file)
        <mx:CheckBox width="100%" label="Dim background" selected="true" id="dim"
            change="Globals.vars.root.tileset.setDimming(dim.selected); Globals.vars.yahoo.alpha = dim.selected ? 0.5 : 1" />
 
+       <mx:Button label="Load vector file..." click="selectVectorSource();"/>
+
        <mx:Script><![CDATA[
                import net.systemeD.halcyon.*;
                import net.systemeD.halcyon.connection.*;
                import net.systemeD.potlatch2.*;
+               import mx.core.*;
+               import mx.managers.PopUpManager;
                import com.yahoo.maps.api.YahooMap;
                import com.yahoo.maps.api.YahooMapEvent;
                import com.yahoo.maps.api.core.location.LatLon;
                                yahoo.visible=false;
                        }
                }
+               
+               private function selectVectorSource():void {
+          var panel:VectorSourceDialog = VectorSourceDialog(
+              PopUpManager.createPopUp(Application(Application.application), VectorSourceDialog, true));
+          PopUpManager.centerPopUp(panel);
+               }
 
     ]]></mx:Script>    
 </mx:VBox>
diff --git a/net/systemeD/potlatch2/VectorSourceDialog.mxml b/net/systemeD/potlatch2/VectorSourceDialog.mxml
new file mode 100644 (file)
index 0000000..8cf2c72
--- /dev/null
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<mx:TitleWindow
+        xmlns:mx="http://www.adobe.com/2006/mxml" 
+        layout="vertical" showCloseButton="true"
+        horizontalAlign="center" title="Load vector file"
+        width="350" height="250" verticalGap="0">
+  <mx:Script><![CDATA[
+       import net.systemeD.halcyon.Map;
+       import net.systemeD.halcyon.Globals;
+       import net.systemeD.halcyon.vectorlayers.*;
+       import net.systemeD.potlatch2.utils.Importer;
+       import net.systemeD.potlatch2.utils.ShpImporter;
+    import mx.managers.PopUpManager;
+    import mx.events.CloseEvent;
+    import mx.core.Application;
+
+    public function init():void {
+        PopUpManager.addPopUp(this, Application(Application.application), true);
+        PopUpManager.centerPopUp(this);
+        this.addEventListener(CloseEvent.CLOSE, vectorDialog_close);
+    }
+    
+    private function vectorDialog_close(evt:CloseEvent):void {
+        PopUpManager.removePopUp(this);
+    }
+
+       private function loadSHP(url:String):void {
+        PopUpManager.removePopUp(this);
+               var theMap:Map = Globals.vars.root;
+               var vectorlayer:CustomVectorLayer=new CustomVectorLayer(theMap,"potlatch.css");
+               theMap.vectorlayers.push(vectorlayer);
+               theMap.vectorbg.addChild(vectorlayer.paint);
+
+               var re:RegExp=/.shp$/i;
+               url=url.replace(re,'');
+
+               var shp:ShpImporter=new ShpImporter(vectorlayer,
+                                                   vectorlayer.paint,
+                                                   [url+".shp",url+".shx",url+".dbf"]);
+       }
+
+              ]]>
+  </mx:Script>
+  <mx:Text>
+    <mx:text>
+      Input the URL of a shapefile to import.
+    </mx:text>
+  </mx:Text>
+  <mx:TextInput id="src" text="" />
+  <mx:ControlBar>
+    <mx:Spacer width="100%"/>
+    <mx:Button label="Ok" click="loadSHP(src.text);"/>
+  </mx:ControlBar>
+
+</mx:TitleWindow>
\ No newline at end of file
index 29a3f7d..a4d6f05 100644 (file)
@@ -65,7 +65,7 @@ package net.systemeD.potlatch2.controller {
                                                  controller.map.coord2lon(event.localX),
                                                  controller.map.coord2latp(event.localY));
                                elastic.end = mouse;
-                       } else if ( event.type == MouseEvent.MOUSE_OVER && focus!=selectedWay) {
+                       } else if ( event.type == MouseEvent.ROLL_OVER && focus!=selectedWay) {
                                controller.map.setHighlight(focus, { showNodesHover: true });
                        } else if ( event.type == MouseEvent.MOUSE_OUT  && focus!=selectedWay) {
                                controller.map.setHighlight(focus, { showNodesHover: false });
index c82c244..2aa5672 100644 (file)
@@ -29,7 +29,7 @@ package net.systemeD.potlatch2.controller {
                                        controller.map.coord2lon(event.localX));
                                var way:Way = controller.connection.createWay({}, [startNode]);
                                return new DrawWay(way, true, false);
-                       } else if ( event.type == MouseEvent.MOUSE_OVER ) {
+                       } else if ( event.type == MouseEvent.ROLL_OVER ) {
                                controller.map.setHighlight(focus, { hover: true });
                        } else if ( event.type == MouseEvent.MOUSE_OUT ) {
                                controller.map.setHighlight(focus, { hover: false });
index b8f4751..536ce16 100644 (file)
@@ -1,5 +1,6 @@
 package net.systemeD.potlatch2.controller {
        import flash.events.*;
+       import flash.ui.Keyboard;
     import net.systemeD.potlatch2.EditController;
     import net.systemeD.halcyon.connection.*;
        import net.systemeD.halcyon.Globals;
@@ -32,7 +33,7 @@ package net.systemeD.potlatch2.controller {
         }
         
         override public function processMouseEvent(event:MouseEvent, entity:Entity):ControllerState {
-                       if (event.type==MouseEvent.MOUSE_MOVE || event.type==MouseEvent.MOUSE_OVER || event.type==MouseEvent.MOUSE_OUT) { return this; }
+                       if (event.type==MouseEvent.MOUSE_MOVE || event.type==MouseEvent.ROLL_OVER || event.type==MouseEvent.MOUSE_OUT) { return this; }
             var focus:Entity = NoSelection.getTopLevelFocusEntity(entity);
 
             if ( event.type == MouseEvent.MOUSE_UP ) {
@@ -43,12 +44,6 @@ package net.systemeD.potlatch2.controller {
                     return new NoSelection();
                                }
             } else if ( event.type == MouseEvent.MOUSE_DOWN ) {
-//                             if ( entity is Way && focus==selectedWay && event.shiftKey) {
-//                                     // insert node within way (shift-click)
-//                  var d:DragWayNode=new DragWayNode(selectedWay, addNode(event), event);
-//                                     d.forceDragStart();
-//                                     return d;
-//                             } else
                 if ( focus is Node ) {
                                        return new DragPOINode(entity as Node,event,false);
                 } else if ( entity is Node && focus is Way ) {
@@ -59,6 +54,20 @@ package net.systemeD.potlatch2.controller {
             return this;
         }
 
+               override public function processKeyboardEvent(event:KeyboardEvent):ControllerState {
+                       switch (event.keyCode) {
+                               case Keyboard.BACKSPACE:        return deletePOI();
+                               case Keyboard.DELETE:           return deletePOI();
+                       }
+                       return this;
+               }
+               
+               public function deletePOI():ControllerState {
+                       controller.connection.unregisterPOI(selectedNode);
+                       selectedNode.remove();
+                       return new NoSelection();
+               }
+               
         override public function enterState():void {
             selectNode(initNode);
                        Globals.vars.root.addDebug("**** -> "+this);
index e5abe68..a301cfa 100644 (file)
@@ -34,7 +34,7 @@ package net.systemeD.potlatch2.controller {
         }
         
         override public function processMouseEvent(event:MouseEvent, entity:Entity):ControllerState {
-                       if (event.type==MouseEvent.MOUSE_MOVE || event.type==MouseEvent.MOUSE_OVER || event.type==MouseEvent.MOUSE_OUT) { return this; }
+                       if (event.type==MouseEvent.MOUSE_MOVE || event.type==MouseEvent.ROLL_OVER || event.type==MouseEvent.MOUSE_OUT) { return this; }
             var focus:Entity = NoSelection.getTopLevelFocusEntity(entity);
 
             if ( event.type == MouseEvent.MOUSE_UP ) {
@@ -108,7 +108,7 @@ package net.systemeD.potlatch2.controller {
 
         override public function enterState():void {
             selectWay(initWay);
-                       Globals.vars.root.addDebug("**** -> "+this);
+                       Globals.vars.root.addDebug("**** -> "+this+" "+selectedWay.id);
         }
         override public function exitState():void {
             clearSelection();
index 4a5e99b..cea5b8a 100644 (file)
@@ -35,7 +35,7 @@ package net.systemeD.potlatch2.controller {
         }
         
         override public function processMouseEvent(event:MouseEvent, entity:Entity):ControllerState {
-                       if (event.type==MouseEvent.MOUSE_MOVE || event.type==MouseEvent.MOUSE_OVER || event.type==MouseEvent.MOUSE_OUT) { return this; }
+                       if (event.type==MouseEvent.MOUSE_MOVE || event.type==MouseEvent.ROLL_OVER || event.type==MouseEvent.MOUSE_OUT) { return this; }
             var focus:Entity = NoSelection.getTopLevelFocusEntity(entity);
 
             if ( event.type == MouseEvent.MOUSE_UP ) {
@@ -117,7 +117,7 @@ package net.systemeD.potlatch2.controller {
                                // ** needs to copy roles as well
                                r.appendMember(new RelationMember(newWay, ''));
                        }
-                       controller.map.ways[newWay.id].redraw();
+                       controller.map.paint.wayuis[newWay.id].redraw();        // ** should we do this by firing an event?
 
                        return new SelectedWay(selectedWay);
                }
index 4bf94fc..46ee4c3 100644 (file)
@@ -1,7 +1,8 @@
 package net.systemeD.potlatch2.utils {
 
-       import net.systemeD.halcyon.Map;
+       import net.systemeD.halcyon.MapPaint;
        import net.systemeD.halcyon.ExtendedURLLoader;
+       import flash.net.URLLoader;
        import flash.display.LoaderInfo;
        import flash.events.*;
        import flash.net.*;
@@ -10,14 +11,20 @@ package net.systemeD.potlatch2.utils {
 
        public class Importer {
 
-               protected var map:Map;
-               protected var files:Array=[];
+               protected var container:Object;                         // destination object for way/node/relations data
+               protected var paint:MapPaint;                           // destination sprite for WayUIs/NodeUIs
+
+               public var files:Array=[];
                protected var filenames:Array;
                protected var filesloaded:uint=0;
+               protected var callback:Function;
 
-               public function Importer(map:Map, filenames:Array) {
+               public function Importer(container:*, paint:MapPaint, filenames:Array) {
                        Globals.vars.root.addDebug("starting importer"); 
-                       this.map = map;
+                       Globals.vars.root.addDebug("container is "+container);
+                       Globals.vars.root.addDebug("paint is "+paint);
+                       this.container = container;
+                       this.paint = paint;
                        this.filenames=filenames;
 
                        var sp:uint=0;
@@ -27,10 +34,10 @@ package net.systemeD.potlatch2.utils {
                                var loader:ExtendedURLLoader = new ExtendedURLLoader();
                                loader.info['file']=sp;
                                loader.dataFormat=URLLoaderDataFormat.BINARY;
-                               loader.addEventListener(Event.COMPLETE,                                         fileLoaded,                             false, 0, true);
-                               loader.addEventListener(HTTPStatusEvent.HTTP_STATUS,            httpStatusHandler,              false, 0, true);
-                               loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,      securityErrorHandler,   false, 0, true);
-                               loader.addEventListener(IOErrorEvent.IO_ERROR,                          ioErrorHandler,                 false, 0, true);
+                               loader.addEventListener(Event.COMPLETE,                                         fileLoaded);
+                               loader.addEventListener(HTTPStatusEvent.HTTP_STATUS,            httpStatusHandler);
+                               loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,      securityErrorHandler);
+                               loader.addEventListener(IOErrorEvent.IO_ERROR,                          ioErrorHandler);
                                loader.load(new URLRequest(fn));
                                sp++;
                        }
@@ -43,9 +50,10 @@ package net.systemeD.potlatch2.utils {
                        if (filesloaded==filenames.length) { doImport(); }
                }
                
-               protected function doImport():void { }
+               protected function doImport():void {
+               }
 
-               protected function httpStatusHandler( event:HTTPStatusEvent ):void { }
+               protected function httpStatusHandler( event:HTTPStatusEvent ):void { Globals.vars.root.addDebug("httpstatusevent"); }
                protected function securityErrorHandler( event:SecurityErrorEvent ):void { Globals.vars.root.addDebug("securityerrorevent"); }
                protected function ioErrorHandler( event:IOErrorEvent ):void { Globals.vars.root.addDebug("ioerrorevent"); }
 
index 88229ae..b324a25 100644 (file)
@@ -1,31 +1,19 @@
 package net.systemeD.potlatch2.utils {
 
-       import net.systemeD.halcyon.Map;
-       import net.systemeD.halcyon.connection.*;
        import org.vanrijkom.shp.*;
        import org.vanrijkom.dbf.*;
-
+       import net.systemeD.halcyon.MapPaint;
        import net.systemeD.halcyon.Globals;
+       import net.systemeD.halcyon.connection.Node;
 
-       // SHP class docs and examples:
-       //              http://vanrijkom.org/shp/index.html
-       //              http://www.boxshapedworld.com/blog/post/Shapefiles-Actionscript-30-and-Google-Maps.aspx
-       //              http://web.archive.org/web/20071119113250rn_1/vanrijkom.org/samples/fsd-mexico/srcview/
-       // we load .shp as files[0], .shx as files[1], .dbf as files[2]
-
-       // See http://www.actionscript.org/forums/showthread.php3?t=185320 for tips on avoiding time-outs with big files -
-       // probably needs to be asynchronous
-               
-       public class ShpImporter extends Importer  {
+       public class ShpImporter extends Importer {
 
-               public function ShpImporter(map:Map, filenames:Array) {
-                       super(map, filenames);
+               public function ShpImporter(container:*, paint:MapPaint, filenames:Array) {
+                       super(container,paint,filenames);
                }
-               
-               // All data is loaded, so do the import
 
-               override protected function doImport():void {
-                       Globals.vars.root.addDebug("importing");
+               override protected function doImport(): void {
+                       // we load .shp as files[0], .shx as files[1], .dbf as files[2]
                        var shp:ShpHeader=new ShpHeader(files[0]);
                        var dbf:DbfHeader=new DbfHeader(files[2]);
 
@@ -33,28 +21,29 @@ package net.systemeD.potlatch2.utils {
 
                                // Loop through all polylines in the shape
                                var polyArray:Array = ShpTools.readRecords(files[0]);
-                               for (var i:uint=0; i<Math.min(polyArray.length,50); i++) {
+                               for (var i:uint=0; i<polyArray.length; i++) {
 
                                        // Get attributes like this:
                                        //              var dr:DbfRecord = DbfTools.getRecord(files[2], dbf, i);
                                        //              var xsID:String = dr.values[idFieldName];
 
                                        // Do each ring in turn, then each point in the ring
-                                       for (var j:int=0; j < Math.min(polyArray[i].shape.rings.length,50); j++) {
-                                               var nodes:Array=[];
+                                       for (var j:int=0; j < polyArray[i].shape.rings.length; j++) {
+                                               var nodestring:Array=[];
                                                var points:Array = polyArray[i].shape.rings[j];
                                                if (points!=null) {
-                                                       for (var k:int=0; k < Math.min(points.length,50); k++) {
+                                                       for (var k:int=0; k < points.length; k++) {
                                                                var p:ShpPoint = ShpPoint(points[k]);
-                                               var node:Node = map.connection.createNode({}, p.y, p.x);
-                                                               nodes.push(node);
-                                                               Globals.vars.root.addDebug("point "+p.x+","+p.y);
+                                                               nodestring.push(container.createNode({}, p.y, p.x));
                                                        }
                                                }
-                                               if (nodes.length>0) { var way:Way = map.connection.createWay({}, nodes); }
+                                               if (nodestring.length>0) {
+                                                       paint.createWayUI(container.createWay({}, nodestring));
+                                               }
                                        }
                                }
                        }
                }
+
        }
 }