refactor node stateClasses and stylelist calculation
authorRichard Fairhurst <richard@systemed.net>
Tue, 13 Jul 2010 08:46:12 +0000 (08:46 +0000)
committerRichard Fairhurst <richard@systemed.net>
Tue, 13 Jul 2010 08:46:12 +0000 (08:46 +0000)
18 files changed:
net/systemeD/halcyon/EntityUI.as
net/systemeD/halcyon/Map.as
net/systemeD/halcyon/MapPaint.as
net/systemeD/halcyon/NodeUI.as
net/systemeD/halcyon/VectorLayer.as
net/systemeD/halcyon/WayUI.as
net/systemeD/halcyon/connection/Connection.as
net/systemeD/halcyon/styleparser/Rule.as
net/systemeD/halcyon/styleparser/StyleChooser.as
net/systemeD/halcyon/styleparser/StyleList.as
net/systemeD/potlatch2/controller/DragPOINode.as
net/systemeD/potlatch2/controller/DragWay.as
net/systemeD/potlatch2/controller/DragWayNode.as
net/systemeD/potlatch2/controller/DrawWay.as
net/systemeD/potlatch2/controller/SelectedPOINode.as
net/systemeD/potlatch2/controller/SelectedWay.as
net/systemeD/potlatch2/controller/SelectedWayNode.as
net/systemeD/potlatch2/mapfeatures/editors/Choice.as

index 59552bd..30b5f89 100644 (file)
@@ -12,16 +12,17 @@ package net.systemeD.halcyon {
        public class EntityUI {
 
                protected var entity:Entity;
+               protected var styleList:StyleList;                              // current StyleList for this entity
                protected var sprites:Array=new Array();                // instances in display list
         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 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 paint:MapPaint;                                              // reference to parent MapPaint
                public var ruleset:RuleSet;                                             // reference to ruleset in operation
                public var interactive:Boolean=true;                    // does object respond to clicks?
+               public var purgable:Boolean=true;                               // can it be deleted when offscreen?
 
                protected const FILLSPRITE:uint=0;
                protected const CASINGSPRITE:uint=1;
@@ -66,19 +67,23 @@ package net.systemeD.halcyon {
 
                protected function relationAdded(event:RelationMemberEvent):void {
                    event.relation.addEventListener(Connection.TAG_CHANGED, relationTagChanged);
+                       invalidateStyleList();
                    redraw();
                }
                
                protected function relationRemoved(event:RelationMemberEvent):void {
                    event.relation.removeEventListener(Connection.TAG_CHANGED, relationTagChanged);
+                       invalidateStyleList();
                    redraw();
                }
                
         protected function tagChanged(event:TagEvent):void {
+                       invalidateStyleList();
             redraw();
         }
 
         protected function relationTagChanged(event:TagEvent):void {
+                       invalidateStyleList();
             redraw();
         }
                
@@ -134,15 +139,28 @@ package net.systemeD.halcyon {
                        }
                }
 
-        public function setHighlight(stateType:String, isOn:*):void {
-            if ( isOn && stateClasses[stateType] == null ) {
+        public function setHighlight(settings:Object):void {
+                       var changed:Boolean=false;
+                       for (var stateType:String in settings) {
+                               if (setStateClass(stateType, settings[stateType])) { changed=true; }
+                       }
+                       if (changed) redraw();
+        }
+
+        public function setStateClass(stateType:String, isOn:*):Boolean {
+            if ( isOn && stateClasses[stateType] != isOn ) {
                 stateClasses[stateType] = isOn;
+                               invalidateStyleList();
+                               return true;
             } else if ( !isOn && stateClasses[stateType] != null ) {
                 delete stateClasses[stateType];
+                               invalidateStyleList();
+                               return true;
             }
+                       return false;
         }
 
-               protected function applyStateClasses(tags:Object):Object {
+               public function applyStateClasses(tags:Object):Object {
             for (var stateKey:String in stateClasses) {
                 tags[":"+stateKey] = 'yes';
             }
@@ -155,12 +173,12 @@ package net.systemeD.halcyon {
 
                // Redraw control
                
-               public function redraw(sl:StyleList=null):Boolean {
-                       if (suspended) { redrawStyleList=sl; redrawDue=true; return false; }
-                       return doRedraw(sl);
+               public function redraw():Boolean {
+                       if (suspended) { redrawDue=true; return false; }
+                       return doRedraw();
                }
                
-               public function doRedraw(sl:StyleList):Boolean {
+               public function doRedraw():Boolean {
                        // to be overwritten
                        return false;
                }
@@ -173,11 +191,14 @@ package net.systemeD.halcyon {
                public function resumeRedraw(event:EntityEvent):void {
                        suspended=false;
                        if (redrawDue) { 
-                               doRedraw(redrawStyleList);
+                               doRedraw();
                                redrawDue=false;
-                               redrawStyleList=null; 
                        }
                }
+               
+               public function invalidateStyleList():void {
+                       styleList=null;
+               }
 
        }
 
index b74bf9c..c4c0420 100755 (executable)
@@ -27,7 +27,7 @@ package net.systemeD.halcyon {
                public const MASTERSCALE:Number=5825.4222222222;// master map scale - how many Flash pixels in 1 degree longitude
                                                                                                                // (for Landsat, 5120)
                public const MINSCALE:uint=13;                                  // don't zoom out past this
-               public const MAXSCALE:uint=19;                                  // don't zoom in past this
+               public const MAXSCALE:uint=23;                                  // don't zoom in past this
 
                public var paint:MapPaint;                                              // sprite for ways and (POI/tagged) nodes in core layer
                public var vectorbg:Sprite;                                             // sprite for vector background layers
@@ -254,17 +254,28 @@ package net.systemeD.halcyon {
                }
 
         public function setHighlight(entity:Entity, settings:Object):void {
-                       var stateType:String;
-                       var ui:EntityUI=null;
-                       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]);
-                       }
-                       ui.redraw();
+                       if      ( entity is Way  ) { paint.wayuis[entity.id].setHighlight(settings); }
+                       else if ( entity is Node ) { paint.nodeuis[entity.id].setHighlight(settings); }
+        }
+
+        public function setHighlightOnNodes(way:Way, settings:Object):void {
+                       paint.wayuis[way.id].setHighlightOnNodes(settings);
         }
 
+               public function setPurgable(entity:Entity, purgable:Boolean):void {
+                       if ( entity is Way  ) {
+                               var way:Way=entity as Way;
+                               paint.wayuis[way.id].purgable=purgable;
+                               for (var i:uint=0; i<way.length; i++) {
+                                       if (paint.nodeuis[way.getNode(i).id]) {
+                                               paint.nodeuis[way.getNode(i).id].purgable=purgable;
+                                       }
+                               }
+                       } else if ( entity is Node ) { 
+                               paint.nodeuis[entity.id].purgable=purgable;
+                       }
+               }
+
         // Handle mouse events on ways/nodes
         private var mapController:MapController = null;
 
index e68d8e6..7d46a71 100644 (file)
@@ -105,16 +105,30 @@ package net.systemeD.halcyon {
                                if (!wayuis[way.id]) { createWayUI(way); }
                                else if (redraw) { wayuis[way.id].recalculate(); wayuis[way.id].redraw(); }
                        }
+
                        if (remove) {
-                               for each (way in o.waysOutside) { deleteWayUI(way); }
+                               for each (way in o.waysOutside) {
+                                       if (wayuis[way.id] && !wayuis[way.id].purgable) {
+                                               if (redraw) { wayuis[way.id].recalculate(); wayuis[way.id].redraw(); }
+                                       } else {
+                                               deleteWayUI(way);
+                                       }
+                               }
                        }
 
-                       for each (node in o.poisInside) {
+                       for each (node in o.nodesInside) {
                                if (!nodeuis[node.id]) { createNodeUI(node); }
                                else if (redraw) { nodeuis[node.id].redraw(); }
                        }
+
                        if (remove) {
-                               for each (node in o.poisOutside) { deleteNodeUI(node); }
+                               for each (node in o.nodesOutside) { 
+                                       if (nodeuis[node.id] && !nodeuis[node.id].purgable) {
+                                               if (redraw) { nodeuis[node.id].redraw(); }
+                                       } else {
+                                               deleteNodeUI(node);
+                                       }
+                               }
                        }
                }
 
@@ -133,12 +147,14 @@ package net.systemeD.halcyon {
                        wayuis[way.id].removeSprites();
                        delete wayuis[way.id];
                        for (var i:uint=0; i<way.length; i++) {
-                               deleteNodeUI(way.getNode(i));
+                               var node:Node=way.getNode(i);
+                               if (nodeuis[node.id]) { deleteNodeUI(node); }
                        }
                }
 
                public function deleteNodeUI(node:Node):void {
                        if (!nodeuis[node.id]) { return; }
+                       if (!nodeuis[node.id].purgable) { return; }
                        nodeuis[node.id].removeSprites();
                        delete nodeuis[node.id];
                }
index 1f5264c..350265e 100644 (file)
@@ -20,15 +20,20 @@ package net.systemeD.halcyon {
                private var rotation:Number=0;                          // rotation applied to this POI
                private static const NO_LAYER:int=-99999;
 
-               public function NodeUI(node:Node, paint:MapPaint, heading:Number=0, layer:int=NO_LAYER, sl:StyleList=null) {
+               public function NodeUI(node:Node, paint:MapPaint, heading:Number=0, layer:int=NO_LAYER, stateClasses:Object=null) {
                        super(node,paint);
                        if (layer==NO_LAYER) { this.layer=paint.maxlayer; } else { this.layer=layer; }
                        this.heading = heading;
+                       if (stateClasses) {
+                               for (var state:String in stateClasses) {
+                                       if (stateClasses[state]) { this.stateClasses[state]=stateClasses[state]; }
+                               }
+                       }
             entity.addEventListener(Connection.TAG_CHANGED, tagChanged);
                        entity.addEventListener(Connection.NODE_MOVED, nodeMoved);
                        entity.addEventListener(Connection.NODE_DELETED, nodeDeleted);
             attachRelationListeners();
-                       redraw(sl);
+                       redraw();
                }
                
                public function nodeMoved(event:Event):void {
@@ -38,33 +43,35 @@ package net.systemeD.halcyon {
                public function nodeDeleted(event:Event):void {
                        removeSprites();
                }
-               
-               override public function doRedraw(sl:StyleList):Boolean {
+
+               override public function doRedraw():Boolean {
                        if (!paint.ready) { return false; }
                        if (entity.deleted) { return false; }
 
                        var tags:Object = entity.getTagsCopy();
                        tags=applyStateClasses(tags);
                        if (!entity.hasParentWays) { tags[':poi']='yes'; }
-                       if (!sl) { sl=paint.ruleset.getStyles(entity,tags,paint.map.scale); }
+                       if (!styleList || !styleList.isValidAt(paint.map.scale)) {
+                               styleList=paint.ruleset.getStyles(entity,tags,paint.map.scale); 
+                       }
 
                        var inWay:Boolean=entity.hasParentWays;
-                       var hasStyles:Boolean=sl.hasStyles();
+                       var hasStyles:Boolean=styleList.hasStyles();
                        
                        removeSprites(); iconnames={};
-                       return renderFromStyle(sl,tags);
+                       return renderFromStyle(tags);
                }
 
-               private function renderFromStyle(sl:StyleList,tags:Object):Boolean {
+               private function renderFromStyle(tags:Object):Boolean {
                        var r:Boolean=false;                    // ** rendered
                        var maxwidth:Number=4;                  // biggest width
                        var w:Number;
                        var icon:Sprite;
                        interactive=false;
-                       for each (var sublayer:Number in sl.sublayers) {
+                       for each (var sublayer:Number in styleList.sublayers) {
 
-                               if (sl.pointStyles[sublayer]) {
-                                       var s:PointStyle=sl.pointStyles[sublayer];
+                               if (styleList.pointStyles[sublayer]) {
+                                       var s:PointStyle=styleList.pointStyles[sublayer];
                                        interactive||=s.interactive;
                                        r=true;
                                        if (s.rotation) { rotation=s.rotation; }
@@ -73,7 +80,7 @@ package net.systemeD.halcyon {
                                                        // draw square
                                                        icon=new Sprite();
                                                        addToLayer(icon,STROKESPRITE,sublayer);
-                                                       w=styleIcon(icon,sl,sublayer);
+                                                       w=styleIcon(icon,sublayer);
                                                        icon.graphics.drawRect(0,0,w,w);
                                                        if (s.interactive) { maxwidth=Math.max(w,maxwidth); }
                                                        iconnames[sublayer]='_square';
@@ -82,7 +89,7 @@ package net.systemeD.halcyon {
                                                        // draw circle
                                                        icon=new Sprite();
                                                        addToLayer(icon,STROKESPRITE,sublayer);
-                                                       w=styleIcon(icon,sl,sublayer);
+                                                       w=styleIcon(icon,sublayer);
                                                        icon.graphics.drawCircle(w,w,w);
                                                        if (s.interactive) { maxwidth=Math.max(w,maxwidth); }
                                                        iconnames[sublayer]='_circle';
@@ -100,8 +107,8 @@ package net.systemeD.halcyon {
 
                                // name sprite
                                var a:String='', t:TextStyle;
-                               if (sl.textStyles[sublayer]) {
-                                       t=sl.textStyles[sublayer];
+                               if (styleList.textStyles[sublayer]) {
+                                       t=styleList.textStyles[sublayer];
                                        interactive||=t.interactive;
                                        a=tags[t.text];
                                }
@@ -119,12 +126,12 @@ package net.systemeD.halcyon {
                }
 
 
-               private function styleIcon(icon:Sprite, sl:StyleList, sublayer:Number):Number {
+               private function styleIcon(icon:Sprite, sublayer:Number):Number {
                        loaded=true;
 
                        // get colours
-                       if (sl.shapeStyles[sublayer]) {
-                               var s:ShapeStyle=sl.shapeStyles[sublayer];
+                       if (styleList.shapeStyles[sublayer]) {
+                               var s:ShapeStyle=styleList.shapeStyles[sublayer];
                                if (s.color) { icon.graphics.beginFill(s.color); 
                                        }
                                if (s.casing_width || !isNaN(s.casing_color)) {
@@ -135,7 +142,7 @@ package net.systemeD.halcyon {
                        }
 
                        // return width
-                       return sl.pointStyles[sublayer].icon_width;
+                       return styleList.pointStyles[sublayer].icon_width;
                }
 
                private function addHitSprite(w:uint):void {
index d919e98..b27e0e8 100644 (file)
@@ -51,16 +51,14 @@ package net.systemeD.halcyon {
                public function getObjectsByBbox(left:Number, right:Number, top:Number, bottom:Number):Object {
                        // ** FIXME: this is just copied-and-pasted from Connection.as, which really isn't very
                        // good practice. Is there a more elegant way of doing it?
-                       var o:Object = { poisInside: [], poisOutside: [], waysInside: [], waysOutside: [] };
+                       var o:Object = { nodesInside: [], nodesOutside: [], waysInside: [], waysOutside: [] };
                        for each (var way:Way in ways) {
                                if (way.within(left,right,top,bottom)) { o.waysInside.push(way); }
                                                                  else { o.waysOutside.push(way); }
                        }
                        for each (var node:Node in nodes) {
-                               if (!node.hasParentWays) {
-                                       if (node.within(left,right,top,bottom)) { o.poisInside.push(node); }
-                                                                          else { o.poisOutside.push(node); }
-                               }
+                               if (node.within(left,right,top,bottom)) { o.nodesInside.push(node); }
+                                                                  else { o.nodesOutside.push(node); }
                        }
                        return o;
                }
index adcd6ce..2bf9a95 100755 (executable)
@@ -115,6 +115,16 @@ package net.systemeD.halcyon {
                        }
                }
 
+        public function setHighlightOnNodes(settings:Object):void {
+                       for (var i:uint = 0; i < Way(entity).length; i++) {
+                var node:Node = Way(entity).getNode(i);
+                               if (paint.nodeuis[node.id]) {
+                                       paint.nodeuis[node.id].setHighlight(settings);
+                                       paint.nodeuis[node.id].redraw();
+                               }
+                       }
+        }
+
                // ------------------------------------------------------------------------------------------
                // Calculate length etc.
                // ** this could be made scale-independent - would speed up redraw
@@ -167,7 +177,7 @@ package net.systemeD.halcyon {
                // ------------------------------------------------------------------------------------------
                // Redraw
 
-               override public function doRedraw(sl:StyleList):Boolean {
+               override public function doRedraw():Boolean {
                        interactive=false;
                        removeSprites();
                        if (Way(entity).length==0) { return false; }
@@ -185,8 +195,12 @@ package net.systemeD.halcyon {
                        // Keep track of maximum stroke width for hitzone
                        var maxwidth:Number=4;
 
+                       // Create styleList if not already drawn
+                       if (!styleList || !styleList.isValidAt(paint.map.scale)) {
+                               styleList=paint.ruleset.getStyles(entity, tags, paint.map.scale);
+                       }
+
                        // Iterate through each sublayer, drawing any styles on that layer
-                       if (!sl) { sl=paint.ruleset.getStyles(entity, tags, paint.map.scale); }
                        var drawn:Boolean;
                        var multis:Array=entity.findParentRelationsOfType('multipolygon','outer');
                        var inners:Array=[];
@@ -194,9 +208,9 @@ package net.systemeD.halcyon {
                                inners=inners.concat(m.findMembersByRole('inner'));
                        }
 
-                       for each (var sublayer:Number in sl.sublayers) {
-                               if (sl.shapeStyles[sublayer]) {
-                                       var s:ShapeStyle=sl.shapeStyles[sublayer];
+                       for each (var sublayer:Number in styleList.sublayers) {
+                               if (styleList.shapeStyles[sublayer]) {
+                                       var s:ShapeStyle=styleList.shapeStyles[sublayer];
                                        var stroke:Shape, fill:Shape, casing:Shape, roadname:Sprite;
                                        var x0:Number=paint.map.lon2coord(Way(entity).getNode(0).lon);
                                        var y0:Number=paint.map.latp2coord(Way(entity).getNode(0).latp);
@@ -238,8 +252,8 @@ package net.systemeD.halcyon {
                                        }
                                }
                                
-                               if (sl.textStyles[sublayer]) {
-                                       var t:TextStyle=sl.textStyles[sublayer];
+                               if (styleList.textStyles[sublayer]) {
+                                       var t:TextStyle=styleList.textStyles[sublayer];
                                        interactive||=t.interactive;
                                        roadname=new Sprite(); addToLayer(roadname,NAMESPRITE);
                                        nameformat = t.getTextFormat();
@@ -259,31 +273,24 @@ package net.systemeD.halcyon {
                        }
 
                        // Draw icons
-                       // ** there should be huge potential to optimise this - at present we're
-                       //    running getStyles for every node in the way on every redraw
-                       // ** fix r/heading behaviour - that doesn't look right
                        var r:Number;
-                       var nodetags:Object;
                        var nodeSelected:int=stateClasses["nodeSelected"];
                        for (var i:uint = 0; i < Way(entity).length; i++) {
                 var node:Node = Way(entity).getNode(i);
-                               nodetags=node.getTagsCopy();
-                               if (i==0) { nodetags['_heading']= heading[i]; }
-                                    else { nodetags['_heading']=(heading[i]+heading[i-1])/2; }
-                               if (stateClasses["showNodes"]) { nodetags[':selectedway']='yes'; }
-                               if (stateClasses["showNodesHover"]) { nodetags[':hoverway']='yes'; }
-                               if (node.id==nodeSelected) { nodetags[':selected']='yes'; }
-                               if (node.numParentWays>1) { nodetags[':junction']='yes'; }
-                               sl=paint.ruleset.getStyles(node, nodetags, paint.map.scale);
-                               if (sl.hasStyles()) {
-                                       if (paint.nodeuis[node.id]) {
-                                               paint.nodeuis[node.id].redraw(sl);
-                                       } else {
-                                               paint.nodeuis[node.id]=new NodeUI(node,paint,r,layer,sl);
+                               var nodeStateClasses:Object={};
+//                             if (i==0) { nodetags['_heading']= heading[i]; }
+//                                  else { nodetags['_heading']=(heading[i]+heading[i-1])/2; }
+                               // ** FIXME - heading isn't currently applied
+                               nodeStateClasses['junction']=(node.numParentWays>1);
+
+                               if (paint.nodeuis[node.id]) {
+                                       var nodeui:NodeUI=paint.nodeuis[node.id];
+                                       for (var state:String in nodeStateClasses) {
+                                               nodeui.setStateClass(state,nodeStateClasses[state]);
                                        }
-                               } else if (paint.nodeuis[node.id]) {
-                                       paint.nodeuis[node.id].removeSprites();
-                                       delete paint.nodeuis[node.id];
+                                       nodeui.redraw();
+                               } else {
+                                       paint.nodeuis[node.id]=new NodeUI(node,paint,r,layer,nodeStateClasses);
                                }
                        }
                        if (!drawn) { return false; }
index 629fd7c..5875b7e 100755 (executable)
@@ -284,16 +284,14 @@ package net.systemeD.halcyon.connection {
         }
 
                public function getObjectsByBbox(left:Number, right:Number, top:Number, bottom:Number):Object {
-                       var o:Object = { poisInside: [], poisOutside: [], waysInside: [], waysOutside: [] };
+                       var o:Object = { nodesInside: [], nodesOutside: [], waysInside: [], waysOutside: [] };
                        for each (var way:Way in ways) {
                                if (way.within(left,right,top,bottom)) { o.waysInside.push(way); }
                                                                  else { o.waysOutside.push(way); }
                        }
                        for each (var node:Node in nodes) {
-                               if (!node.hasParentWays) {
-                                       if (node.within(left,right,top,bottom)) { o.poisInside.push(node); }
-                                                                          else { o.poisOutside.push(node); }
-                               }
+                               if (node.within(left,right,top,bottom)) { o.nodesInside.push(node); }
+                                                                  else { o.nodesOutside.push(node); }
                        }
                        return o;
                }
index cb54ed5..ac6a0bb 100644 (file)
@@ -6,8 +6,8 @@ package net.systemeD.halcyon.styleparser {
 
                public var conditions:Array = [];
                public var isAnd:Boolean = true;
-               public var minZoom:uint = 13;                   // ** FIXME: shouldn't be hardcoded
-               public var maxZoom:uint = 19;                   //  |
+               public var minZoom:uint = 0;
+               public var maxZoom:uint = 255;
                public var subject:String='';                   // "", "way", "node" or "relation"
                
                public function Rule(s:String=''):void {
@@ -28,7 +28,7 @@ package net.systemeD.halcyon.styleparser {
                        }
                        return v;
                }
-               
+
                public function toString():String {
                        return subject+" z"+minZoom+"-"+maxZoom+": "+conditions;
                }
index 8270b3f..988d8db 100755 (executable)
@@ -23,8 +23,9 @@ package net.systemeD.halcyon.styleparser {
 
                */
 
-               public var ruleChains:Array=[[]];               // array of array of Rules
-               public var styles:Array=[];                             // array of ShapeStyle/ShieldStyle/TextStyle/PointStyle
+               public var ruleChains:Array=[[]];                       // array of array of Rules
+               public var styles:Array=[];                                     // array of ShapeStyle/ShieldStyle/TextStyle/PointStyle
+               public var zoomSpecific:Boolean=false;          // are any of the rules zoom-specific?
 
                private var rcpos:uint=0;
                private var stylepos:uint=0;
@@ -32,8 +33,9 @@ package net.systemeD.halcyon.styleparser {
                // Update the current StyleList from this StyleChooser
 
                public function updateStyles(obj:Entity, tags:Object, sl:StyleList, imageWidths:Object, zoom:uint):void {
+                       if (zoomSpecific) { sl.validAt=zoom; }
+
                        // Are any of the ruleChains fulfilled?
-                       // ** needs to cope with min/max zoom
                        var w:Number;
                        var fulfilled:Boolean=false;
                        for each (var c:Array in ruleChains) {
@@ -129,6 +131,7 @@ package net.systemeD.halcyon.styleparser {
                public function addZoom(z1:uint,z2:uint):void {
                        ruleChains[rcpos][ruleChains[rcpos].length-1].minZoom=z1;
                        ruleChains[rcpos][ruleChains[rcpos].length-1].maxZoom=z2;
+                       zoomSpecific=true;
                }
                
                // addCondition <- adds into the current ruleChain (existing Rule)
index 7822444..a5ac01c 100755 (executable)
@@ -17,6 +17,7 @@ package net.systemeD.halcyon.styleparser {
                public var shieldStyles:Object={};
                public var maxwidth:Number=0;
                public var sublayers:Array=[];
+               public var validAt:int=-1;                              // zoom level at which this StyleList is valid, or -1 for all
 
                public function hasStyles():Boolean {
                        return ( hasShapeStyles() || hasTextStyles() || hasPointStyles() || hasShieldStyles() );
@@ -36,6 +37,10 @@ package net.systemeD.halcyon.styleparser {
                        return str;
                }
 
+               public function isValidAt(zoom:uint):Boolean {
+                       return (validAt==-1 || validAt==zoom);
+               }
+
                private function hasShapeStyles():Boolean  { for (var a:String in shapeStyles ) { return true; }; return false; }
                private function hasTextStyles():Boolean   { for (var a:String in textStyles  ) { return true; }; return false; }
                private function hasPointStyles():Boolean  { for (var a:String in pointStyles ) { return true; }; return false; }
index e8cc8f9..0f5f122 100644 (file)
@@ -54,11 +54,11 @@ package net.systemeD.potlatch2.controller {
                }
 
         override public function enterState():void {
-            controller.map.setHighlight(selectedNode, { highlight: true } );
+            controller.map.setHighlight(selectedNode, { selected: true } );
                        Globals.vars.root.addDebug("**** -> "+this);
         }
         override public function exitState(newState:ControllerState):void {
-            controller.map.setHighlight(selectedNode, { highlight: false } );
+            controller.map.setHighlight(selectedNode, { selected: false } );
                        Globals.vars.root.addDebug("**** <- "+this);
         }
         override public function toString():String {
index fb67ca6..9203139 100644 (file)
@@ -69,11 +69,11 @@ package net.systemeD.potlatch2.controller {
                }
 
         override public function enterState():void {
-            controller.map.setHighlight(selectedWay, { highlight: true } );
+            controller.map.setHighlight(selectedWay, { selected: true } );
                        Globals.vars.root.addDebug("**** -> "+this);
         }
         override public function exitState(newState:ControllerState):void {
-            controller.map.setHighlight(selectedWay, { highlight: false } );
+            controller.map.setHighlight(selectedWay, { selected: false } );
                        Globals.vars.root.addDebug("**** <- "+this);
         }
         override public function toString():String {
index eb48f29..7760ee0 100644 (file)
@@ -36,7 +36,6 @@ package net.systemeD.potlatch2.controller {
                                if (dragstate==DRAGGING) {
                                        // mouse-up while dragging, so end drag
                        return new SelectedWayNode(selectedWay,draggingIndex);
-//                     return endDrag();
                                } else if (event.shiftKey && !isNew) {
                                        // start new way
                                        var way:Way = controller.connection.createWay({}, [entity],
@@ -74,10 +73,6 @@ package net.systemeD.potlatch2.controller {
                        return this;
                }
 
-        private function endDrag():ControllerState {
-            return previousState;
-        }
-        
         private function dragTo(event:MouseEvent):ControllerState {
                        draggingNode.setLatLon( controller.map.coord2lat(event.localY),
                                     controller.map.coord2lon(event.localX),
@@ -90,11 +85,13 @@ package net.systemeD.potlatch2.controller {
                }
 
         override public function enterState():void {
-            controller.map.setHighlight(selectedWay, { showNodes: true } );
+                       controller.map.setHighlightOnNodes(selectedWay, { selectedway: true } );
+                       controller.map.setHighlight(draggingNode, { selected: true } );
                        Globals.vars.root.addDebug("**** -> "+this);
         }
         override public function exitState(newState:ControllerState):void {
-            controller.map.setHighlight(selectedWay, { showNodes: false } );
+                       controller.map.setHighlightOnNodes(selectedWay, { selectedway: false } );
+                       controller.map.setHighlight(draggingNode, { selected: false } );
                        Globals.vars.root.addDebug("**** <- "+this);
         }
         override public function toString():String {
index 6a05f9a..b63bc3b 100644 (file)
@@ -54,8 +54,8 @@ package net.systemeD.potlatch2.controller {
                                                }
                                        } else {
                                                appendNode(entity as Node, MainUndoStack.getGlobalStack().addAction);
-                                               controller.map.setHighlight(focus, { showNodesHover: false });
-                                               controller.map.setHighlight(selectedWay, { showNodes: true });
+                                               controller.map.setHighlightOnNodes(focus as Way, { hoverway: false });
+                                               controller.map.setHighlight(entity, { selectedway: true });
                                                resetElastic(entity as Node);
                                                lastClick=entity;
                                                if (selectedWay.getNode(0)==selectedWay.getNode(selectedWay.length-1)) {
@@ -80,8 +80,8 @@ package net.systemeD.potlatch2.controller {
                                        }
                                        resetElastic(node);
                                        lastClick=node;
-                                       controller.map.setHighlight(entity, { showNodesHover: false });
-                                       controller.map.setHighlight(selectedWay, { showNodes: true });
+                                       controller.map.setHighlightOnNodes(entity as Way, { hoverway: false });
+                                       controller.map.setHighlightOnNodes(selectedWay, { selectedway: true });
                                }
                                lastClickTime=new Date();
                        } else if ( event.type == MouseEvent.MOUSE_MOVE ) {
@@ -92,7 +92,7 @@ package net.systemeD.potlatch2.controller {
                        } else if ( event.type == MouseEvent.ROLL_OVER ) {
                                if (focus!=selectedWay) {
                                        hoverEntity=focus;
-                                       controller.map.setHighlight(focus, { showNodesHover: true });
+                                       controller.map.setHighlightOnNodes(focus as Way, { hoverway: true });
                                }
                                if (entity is Node && focus is Way && Way(focus).endsWith(Node(entity))) {
                                        if (focus==selectedWay) { controller.setCursor(controller.pen_so); }
@@ -105,14 +105,8 @@ package net.systemeD.potlatch2.controller {
                        } else if ( event.type == MouseEvent.MOUSE_OUT ) {
                                if (entity!=selectedWay) {
                                        hoverEntity=null;
-                                       controller.map.setHighlight(focus, { showNodesHover: false });
-                                       controller.map.setHighlight(selectedWay, { showNodes: true });
-                                       // ** this call to setHighlight(selectedWay) is necessary in case the hovered way (blue nodes)
-                                       // shares any nodes with the selected way (red nodes): if they do, they'll be wiped out by the
-                                       // first call.
-                                       // Ultimately we should fix this by referring to 'way :selected nodes' instead of 'nodes :selectedway'.
-                                       // But this will do for now.
-                                       // We could do with an optional way of calling WayUI.redraw to only do the nodes, which would be a
+                                       controller.map.setHighlightOnNodes(focus as Way, { hoverway: false });
+                                       // ** We could do with an optional way of calling WayUI.redraw to only do the nodes, which would be a
                                        // useful optimisation.
                                }
                                controller.setCursor(controller.pen);
@@ -141,12 +135,12 @@ package net.systemeD.potlatch2.controller {
                
                protected function stopDrawing():ControllerState {
                        if ( hoverEntity ) {
-                               controller.map.setHighlight(hoverEntity, { showNodesHover: false });
+                               controller.map.setHighlightOnNodes(hoverEntity as Way, { hoverway: false });
                                hoverEntity = null;
                        }
 
                        if ( selectedWay.length<2) {
-                               controller.map.setHighlight(selectedWay, { showNodes: false });
+                               controller.map.setHighlightOnNodes(selectedWay, { selectedway: false });
                                selectedWay.remove(MainUndoStack.getGlobalStack().addAction);
                                // delete controller.map.ways[selectedWay.id];
                                return new NoSelection();
@@ -167,6 +161,8 @@ package net.systemeD.potlatch2.controller {
                        appendNode(node, undo.push);
                        
                        MainUndoStack.getGlobalStack().addAction(undo);
+                       controller.map.setHighlight(node, { selectedway: true });
+                       controller.map.setPurgable(node, false);
                        return node;
                }
                
@@ -191,6 +187,7 @@ package net.systemeD.potlatch2.controller {
                                newDraw=0;
                        }
                        if (node.numParentWays==1 && selectedWay.hasOnceOnly(node)) {
+                               controller.map.setPurgable(node, true);
                                controller.connection.unregisterPOI(node);
                                node.remove(undo.push);
                        }
index fa278fd..e22c157 100644 (file)
@@ -55,10 +55,12 @@ package net.systemeD.potlatch2.controller {
 
         override public function enterState():void {
             selectNode(initNode);
+                       controller.map.setPurgable(selectedNode,false);
                        Globals.vars.root.addDebug("**** -> "+this);
         }
         override public function exitState(newState:ControllerState):void {
                        controller.clipboards['node']=selectedNode.getTagsCopy();
+                       controller.map.setPurgable(selectedNode,true);
             clearSelection(newState);
                        Globals.vars.root.addDebug("**** <- "+this);
         }
index 23ba563..88883c8 100644 (file)
@@ -24,14 +24,16 @@ package net.systemeD.potlatch2.controller {
 
             clearSelection(this);
             controller.setSelectedEntity(way);
-            controller.map.setHighlight(way, { selected: true, showNodes: true, hover: false });
+            controller.map.setHighlight(way, { selected: true, hover: false });
+            controller.map.setHighlightOnNodes(way, { selectedway: true });
             selectedWay = way;
             initWay = way;
         }
 
         protected function clearSelection(newState:ControllerState):void {
             if ( selectedWay != null ) {
-               controller.map.setHighlight(selectedWay, { selected: false, showNodes: false, hover: false });
+               controller.map.setHighlight(selectedWay, { selected: false, hover: false });
+               controller.map.setHighlightOnNodes(selectedWay, { selectedway: false });
                 if (!newState.isSelectionState()) { controller.setSelectedEntity(null); }
                 selectedWay = null;
             }
@@ -119,10 +121,12 @@ package net.systemeD.potlatch2.controller {
 
         override public function enterState():void {
             selectWay(initWay);
+                       controller.map.setPurgable(selectedWay,false);
                        Globals.vars.root.addDebug("**** -> "+this+" "+selectedWay.id);
         }
         override public function exitState(newState:ControllerState):void {
                        controller.clipboards['way']=selectedWay.getTagsCopy();
+                       controller.map.setPurgable(selectedWay,true);
             clearSelection(newState);
                        Globals.vars.root.addDebug("**** <- "+this);
         }
index 13e9ba5..576e39a 100644 (file)
@@ -22,7 +22,9 @@ package net.systemeD.potlatch2.controller {
 
             clearSelection(this);
             controller.setSelectedEntity(node);
-            controller.map.setHighlight(way, { hover: false, showNodes: true, nodeSelected: node.id });
+            controller.map.setHighlight(way, { hover: false });
+            controller.map.setHighlight(node, { selected: true });
+            controller.map.setHighlightOnNodes(way, { selectedway: true });
             selectedWay = way; initWay = way;
                        selectedIndex = index; initIndex = index;
             selectedNode = node;
@@ -30,7 +32,9 @@ package net.systemeD.potlatch2.controller {
                 
         override protected function clearSelection(newState:ControllerState):void {
             if ( selectedNode != null ) {
-               controller.map.setHighlight(selectedWay, { selected: false, showNodes: false, nodeSelected: null });
+               controller.map.setHighlight(selectedWay, { selected: false });
+                               controller.map.setHighlight(selectedNode, { selected: false });
+                               controller.map.setHighlightOnNodes(selectedWay, { selectedway: false });
                 if (!newState.isSelectionState()) { controller.setSelectedEntity(null); }
                 selectedNode = null;
                                selectedWay = null;
@@ -73,10 +77,12 @@ package net.systemeD.potlatch2.controller {
                
                override public function enterState():void {
             selectNode(initWay,initIndex);
+                       controller.map.setPurgable(selectedNode,false);
                        Globals.vars.root.addDebug("**** -> "+this);
         }
                override public function exitState(newState:ControllerState):void {
                        controller.clipboards['node']=selectedNode.getTagsCopy();
+                       controller.map.setPurgable(selectedNode,true);
             clearSelection(newState);
                        Globals.vars.root.addDebug("**** <- "+this);
         }
@@ -102,6 +108,8 @@ package net.systemeD.potlatch2.controller {
                        if (selectedWay.getNode(0                   ) == selectedNode) { return this; }
                        if (selectedWay.getNode(selectedWay.length-1) == selectedNode) { return this; }
 
+                       controller.map.setHighlightOnNodes(selectedWay, { selectedway: false } );
+                       controller.map.setPurgable(selectedWay,true);
             MainUndoStack.getGlobalStack().addAction(new SplitWayAction(selectedWay, selectedNode));
 
                        return new SelectedWay(selectedWay);
@@ -116,6 +124,7 @@ package net.systemeD.potlatch2.controller {
                }
                
                public function deleteNode():ControllerState {
+                       controller.map.setPurgable(selectedNode,true);
                        selectedNode.remove(MainUndoStack.getGlobalStack().addAction);
                        return new SelectedWay(selectedWay);
                }
index 93acb03..2b390c1 100644 (file)
@@ -11,7 +11,7 @@ package net.systemeD.potlatch2.mapfeatures.editors {
         public var description:String = "";
         [Bindable]
         public var value:String = null;
-        [Bindable("iconLoaded")]
+        [Bindable(event="iconLoaded")]
         public var icon:ByteArray = null;
 
         private var _match:RegExp = null;