First cut at styling TIGER data via an option. Needs lots of propagation of uid and...
[potlatch2.git] / net / systemeD / halcyon / VectorLayer.as
1 package net.systemeD.halcyon {
2
3         import net.systemeD.halcyon.Map;
4         import net.systemeD.halcyon.MapPaint;
5         import net.systemeD.halcyon.connection.*;
6     import net.systemeD.halcyon.connection.actions.*;
7         import net.systemeD.halcyon.Globals;
8         import net.systemeD.halcyon.styleparser.RuleSet;
9
10         public class VectorLayer extends Object {
11
12                 public var map:Map;
13                 public var paint:MapPaint;                                              // sprites
14                 public var name:String;
15                 public var url:String;
16                 public var style:String='';
17
18                 public var ways:Object=new Object();                    // geodata
19                 public var nodes:Object=new Object();                   //  |
20                 public var relations:Object=new Object();               //  |
21         private var negativeID:Number = -1;
22
23                 public function VectorLayer(n:String,m:Map,s:String) {
24                         name=n;
25                         map=m;
26                         style=s;
27                         paint=new MapPaint(m,0,0);
28                         redrawFromCSS(style);
29                 }
30
31                 public function redrawFromCSS(style:String):void {
32                         paint.ruleset=new RuleSet(map.MINSCALE,map.MAXSCALE,paint.redraw);
33                         paint.ruleset.loadFromCSS(style);
34                 }
35                 
36                 public function createNode(tags:Object,lat:Number,lon:Number):Node {
37                         var node:Node = new Node(negativeID, 0, tags, true, lat, lon);
38                         nodes[negativeID]=node; negativeID--;
39                         return node;
40                 }
41                 public function createWay(tags:Object,nodes:Array):Way {
42                         var way:Way = new Way(negativeID, 0, tags, true, nodes.concat());
43                         ways[negativeID]=way; negativeID--;
44                         return way;
45                 }
46                 public function createRelation(tags:Object,members:Array):Relation {
47             var relation:Relation = new Relation(negativeID, 0, tags, true, members.concat());
48                         relations[negativeID]=relation; negativeID--;
49             return relation;
50                 }
51
52                 public function getObjectsByBbox(left:Number, right:Number, top:Number, bottom:Number):Object {
53                         // ** FIXME: this is just copied-and-pasted from Connection.as, which really isn't very
54                         // good practice. Is there a more elegant way of doing it?
55                         var o:Object = { nodesInside: [], nodesOutside: [], waysInside: [], waysOutside: [] };
56                         for each (var way:Way in ways) {
57                                 if (way.within(left,right,top,bottom)) { o.waysInside.push(way); }
58                                                                   else { o.waysOutside.push(way); }
59                         }
60                         for each (var node:Node in nodes) {
61                                 if (node.within(left,right,top,bottom)) { o.nodesInside.push(node); }
62                                                                    else { o.nodesOutside.push(node); }
63                         }
64                         return o;
65                 }
66                 
67                 public function pullThrough(entity:Entity,connection:Connection):Entity {
68                         var i:uint=0;
69                         var oldNode:Node, newNode:Node;
70                         if (entity is Way) {
71                                 // copy way through to main layer
72                                 // ** shouldn't do this if the nodes are already in the main layer
73                                 //    (or maybe we should just match on lat/long to avoid ways in background having nodes in foreground)
74                                 var oldWay:Way=Way(entity);
75                                 var newWay:Way=connection.createWay(oldWay.getTagsCopy(), [], MainUndoStack.getGlobalStack().addAction);
76                                 var nodemap:Object={};
77                                 for (i=0; i<oldWay.length; i++) {
78                                         oldNode = oldWay.getNode(i);
79                                         newNode = nodemap[oldNode.id] ? nodemap[oldNode.id] : connection.createNode(
80                                                 oldNode.getTagsCopy(), oldNode.lat, oldNode.lon, 
81                                                 MainUndoStack.getGlobalStack().addAction);
82                                         newWay.appendNode(newNode, MainUndoStack.getGlobalStack().addAction);
83                                         nodemap[oldNode.id]=newNode;
84                                 }
85                                 // delete this way
86                                 while (oldWay.length) { 
87                                         var id:Number=oldWay.getNode(0).id;
88                                         oldWay.removeNodeByIndex(0,MainUndoStack.getGlobalStack().addAction,false);
89                                         delete nodes[id];
90                                 }
91                                 paint.wayuis[oldWay.id].redraw();
92                                 delete ways[oldWay.id];
93                                 map.paint.createWayUI(newWay);
94                                 return newWay;
95
96                         } else if (entity is Node && !entity.hasParentWays) {
97                                 // copy node through to main layer
98                                 // ** should be properly undoable
99                                 oldNode=Node(entity)
100                                 var newPoiAction:CreatePOIAction = new CreatePOIAction(
101                                         oldNode.getTagsCopy(), oldNode.lat, oldNode.lon);
102                                 MainUndoStack.getGlobalStack().addAction(newPoiAction);
103                                 paint.deleteNodeUI(oldNode);
104                                 delete nodes[oldNode.id];
105                                 return newPoiAction.getNode();
106                         }
107                         return null;
108                 }
109                 
110                 public function blank():void {
111                         for each (var node:Node in nodes) { paint.deleteNodeUI(node); }
112                         for each (var way:Way in ways) { paint.deleteWayUI(way); }
113                         relations={}; nodes={}; ways={};
114                 }
115
116         }
117 }