add in-map node/way browser
[rails.git] / app / views / browse / start.rjs
1 page.replace_html :sidebar_title, 'Browse'
2 page.replace_html :sidebar_content, :partial => 'start'
3 page << <<EOJ
4  var gml, sf, obj_list, currentFeature;
5  OpenLayers.Feature.Vector.style['default'].strokeWidth = 3;
6  OpenLayers.Feature.Vector.style['default'].cursor = "pointer";
7  function start() {
8    openSidebar({ onclose: stopBrowse });
9    vectors = new OpenLayers.Layer.Vector("Vector Layer", {
10      displayInLayerSwitcher: false
11    });
12  
13    box = new OpenLayers.Control.DrawFeature(vectors, OpenLayers.Handler.RegularPolygon, { 
14      handlerOptions: {
15        sides: 4,
16        snapAngle: 90,
17        irregular: true,
18        persist: true,
19        callbacks: { done: endDrag }
20      }
21    });
22    map.addControl(box);
23  }
24  function stopBrowse() {
25      if (gml) {
26        gml.destroy();
27        gml = null; 
28      } 
29      if (sf) {   
30          sf.destroy();  
31          sf = null;
32      }  
33  }
34  function startDrag() {
35    $("drag_box").innerHTML='Drag a box on the map to select an area';
36     box.activate(); 
37     return false;
38  };
39
40  $("drag_box").onclick = startDrag;
41   
42   function useMap() {
43       var bounds = map.getExtent();
44       setBounds(bounds);
45       getData(bounds); 
46   }
47   $("use_map").onclick = useMap;
48   function dataLoaded() { 
49       $("status").innerHTML = "Loaded " + this.features.length + " features. (<a href='"+ this.url+"'>API</a>)";
50       
51       obj_list = document.createElement("ul");
52       for (var i = 0; i < this.features.length; i++) {
53           var feature = this.features[i]; 
54           var type ="way";
55           if (feature.geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
56               type = "node";
57           }   
58           var nice_name = type.substr(0,1).toUpperCase() + type.substr(1,type.length); 
59           var li = document.createElement("li");
60           li.appendChild(document.createTextNode(nice_name + " "));
61           var link = document.createElement("a");
62           link.href =  "/browse/"+type+"/"+feature.osm_id;
63           var name = feature.attributes.name || feature.osm_id;
64           link.appendChild(document.createTextNode(name));
65           li.appendChild(link);
66           li.appendChild(document.createTextNode(" "));
67           var link = document.createElement("a");
68           link.href =  "#";
69           link.appendChild(document.createTextNode("+"));
70           link.feature = feature;
71           link.onclick = OpenLayers.Function.bind(function() { 
72             var layer = this.feature.layer;
73             for (var i = 0; i < layer.selectedFeatures.length; i++) {
74                 var f = layer.selectedFeatures[i]; 
75                 layer.drawFeature(f, layer.styleMap.createSymbolizer(f, "default"));
76             }
77             on_feature_hover(this.feature);
78             map.setCenter(this.feature.geometry.getBounds().getCenterLonLat());  
79           }, link);   
80           li.appendChild(link);
81           obj_list.appendChild(li);
82       }
83       $("object").innerHTML = "";
84       $("object").appendChild(obj_list); 
85   }
86   function getData(bounds) {
87     $("status").innerHTML = "Loading...";
88     bounds.transform(new OpenLayers.Projection("EPSG:900913"), new OpenLayers.Projection("EPSG:4326"));
89     var url = "/api/0.5/map?bbox="+bounds.toBBOX();
90     if (!gml) {
91         var def = OpenLayers.Feature.Vector.style['default'];
92         var style = new OpenLayers.Style();
93         style.addRules([new OpenLayers.Rule( 
94           {'symbolizer': 
95             {"Polygon": {'fillColor': '#ff0000', 'strokeColor': '#ff0000'},
96              "Line": {'fillColor': '#ffff00', 'strokeColor': '#000000', strokeOpacity: '0.4'},
97              "Point": {'fillColor': '#00ff00', 'strokeColor': '#00ff00'}}
98           }
99         )]);
100         gml = new OpenLayers.Layer.GML("Data",url, 
101                 {format: OpenLayers.Format.OSM, formatOptions: {checkTags: true},
102                  styleMap: new OpenLayers.StyleMap({'default': style, 'select': {'strokeColor': '#0000ff'}})
103                 }
104         );
105         gml.events.register("loadend", gml, dataLoaded );
106         map.addLayer(gml);
107         sf = new OpenLayers.Control.SelectFeature(gml, {'onSelect': on_feature_hover});
108         map.addControl(sf);
109         sf.activate();
110
111     } else {
112         gml.setUrl(url);
113     }
114   }
115   function endDrag(bbox) {
116     var bounds = bbox.getBounds();
117     setBounds(bounds);
118     box.deactivate();
119     getData(bounds);
120     $("drag_box").innerHTML = "Select an area to see features";
121
122   }
123   function loadObjList() {
124       $("object").innerHTML="";
125       $("object").appendChild(obj_list);
126   }
127     
128   function on_feature_hover(feature) {
129       if (currentFeature) {
130         currentFeature.layer.drawFeature(
131           currentFeature, currentFeature.layer.styleMap.createSymbolizer(currentFeature, "default")
132         );
133       }
134       feature.layer.drawFeature(
135         feature, feature.layer.styleMap.createSymbolizer(feature, "select")
136       );
137       if ($("object").firstChild == $("object").obj_list) { 
138         $("object").removeChild(obj_list);
139       } else { 
140         $("object").innerHTML = "";
141       }   
142       var div = document.createElement("div");
143       var link = document.createElement("a");
144       link.href="#";
145       link.onclick = loadObjList;
146       link.appendChild(document.createTextNode("Back to Object List"));
147       div.appendChild(link)
148       $("object").appendChild(div);    
149       var ul = document.createElement("ul");
150       var type ="way";
151       if (feature.geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
152           type = "node";
153       }    
154       var li = document.createElement("li");
155       var link = document.createElement("a");   
156       link.href =  "/browse/"+type+"/"+feature.osm_id;
157       link.appendChild(document.createTextNode(feature.osm_id));
158       li.appendChild(link);
159       ul.appendChild(li);
160       for (var key in feature.attributes) {
161           var li = document.createElement("li"); 
162           li.appendChild(document.createTextNode(key + ": " + feature.attributes[key]));
163           ul.appendChild(li);
164       }
165       $("object").appendChild(ul);
166       currentFeature = feature; 
167   }   
168   function setBounds(bounds) {
169     var epsg4326 = new OpenLayers.Projection("EPSG:4326");
170     var decimals = Math.pow(10, Math.floor(map.getZoom() / 3));
171
172     bounds = bounds.clone().transform(map.getProjectionObject(), epsg4326);
173
174     $("minlon").innerHTML = Math.round(bounds.left * decimals) / decimals;
175     $("minlat").innerHTML = Math.round(bounds.bottom * decimals) / decimals;
176     $("maxlon").innerHTML = Math.round(bounds.right * decimals) / decimals;
177     $("maxlat").innerHTML = Math.round(bounds.top * decimals) / decimals;
178   }
179
180 start();
181 EOJ