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.*; import net.systemeD.halcyon.connection.actions.CreatePOIAction; import net.systemeD.halcyon.styleparser.RuleSet; /** Manages the drawing of map entities, allocating their sprites etc. */ public class MapPaint extends Sprite { /** Parent Map - required for finding out bounds and scale */ public var map:Map; /** Source data for this MapPaint layer */ public var connection:Connection; /** Lowest OSM layer that can be displayed */ public var minlayer:int; /** Highest OSM layer that can be displayed */ public var maxlayer:int; /** The MapCSS rules used for drawing entities. */ public var ruleset:RuleSet; /** WayUI objects attached to Way entities that are currently visible. */ private var wayuis:Object=new Object(); /** NodeUI objects attached to POI/tagged node entities that are currently visible. */ private var nodeuis:Object=new Object(); /** MarkerUI objects attached to Marker entities that are currently visible. */ private var markeruis:Object=new Object(); /** Is this a background layer or the core paint object? */ public var isBackground:Boolean = true; /** Hash of index->position */ public var sublayerIndex:Object={}; /** The url of the style in use */ public var style:String = ''; private const VERYBIG:Number=Math.pow(2,16); private static const NO_LAYER:int=-99999; // same as NodeUI // Set up layering /** Creates paint sprites and hit sprites for all layers in range. This object ends up with a series of child sprites * as follows: p0,p1,p2..px, h0,h1,h2..hx where p are "paint sprites" and "h" are "hit sprites". There is one of each type for each layer. *
Each paint sprite has 4 child sprites (fill, casing, stroke, names). Each hit sprite has 2 child sprites (way hit tests, node hit tests).
*Thus if layers range from -5 to +5, there will be 11 top level paint sprites followed by 11 top level hit sprites.
* * @param map The Map this is attached to. (Required for finding out bounds and scale.) * @param connection The Connection containing the data for this layer. * @param minlayer The lowest OSM layer to display. * @param maxlayer The highest OSM layer to display. * */ public function MapPaint(map:Map, connection:Connection, styleurl:String, minlayer:int, maxlayer:int) { mouseEnabled=false; this.map=map; this.connection=connection; this.minlayer=minlayer; this.maxlayer=maxlayer; sublayerIndex[1]=0; var s:Sprite, l:int; // Set up stylesheet setStyle(styleurl); // Listen for changes on this Connection connection.addEventListener(Connection.NEW_WAY, newWayCreatedListener); connection.addEventListener(Connection.NEW_POI, newPOICreatedListener); connection.addEventListener(Connection.WAY_RENUMBERED, wayRenumberedListener); connection.addEventListener(Connection.NODE_RENUMBERED, nodeRenumberedListener); connection.addEventListener(Connection.NEW_MARKER, newMarkerCreatedListener); // Add paint sprites for (l=minlayer; l<=maxlayer; l++) { // each layer (10 is +5, 0 is -5) s = getPaintSprite(); // | s.addChild(getPaintSprite()); // | 0 fill s.addChild(getPaintSprite()); // | 1 casing var t:Sprite = getPaintSprite(); // | 2 stroke t.addChild(getPaintSprite()); // | | sublayer s.addChild(t); // | | s.addChild(getPaintSprite()); // | 3 names addChild(s); // | } // Add hit sprites for (l=minlayer; l<=maxlayer; l++) { // each layer (21 is +5, 11 is -5) s = getHitSprite(); // | s.addChild(getHitSprite()); // | 0 way hit tests s.addChild(getHitSprite()); // | 1 node hit tests addChild(s); } } /** Returns the paint surface for the given layer. */ public function getPaintSpriteAt(l:int):Sprite { return getChildAt(l-minlayer) as Sprite; } /** Returns the hit sprite for the given layer. */ public function getHitSpriteAt(l:int):Sprite { return getChildAt((l-minlayer) + (maxlayer-minlayer+1)) as Sprite; } /** Is ruleset loaded? */ public function get ready():Boolean { if (!ruleset) { return false; } if (!ruleset.loaded) { return false; } return true; } public function sublayer(layer:int,sublayer:Number):Sprite { var l:DisplayObject; var o:DisplayObject; var index:String, ix:Number; if (!sublayerIndex.hasOwnProperty(sublayer)) { // work out which position to add at var lowestAbove:Number=VERYBIG; var lowestAbovePos:int=-1; var indexLength:uint=0; for (index in sublayerIndex) { ix=Number(index); if (ix>sublayer && ix