1 page.replace_html :sidebar_title, 'Data'
 
   2 page.replace_html :sidebar_content, :partial => 'start'
 
   6   var browseMode = "auto";
 
   9   var browseActiveFeature;
 
  11   var browseSelectControl;
 
  14   OpenLayers.Feature.Vector.style['default'].strokeWidth = 3;
 
  15   OpenLayers.Feature.Vector.style['default'].cursor = "pointer";
 
  17   function startBrowse() {
 
  18     openSidebar({ onclose: stopBrowse });
 
  20     var vectors = new OpenLayers.Layer.Vector();
 
  22     browseBoxControl = new OpenLayers.Control.DrawFeature(vectors, OpenLayers.Handler.RegularPolygon, { 
 
  28         callbacks: { done: endDrag }
 
  31     map.addControl(browseBoxControl);
 
  33     map.events.register("moveend", map, showData);
 
  34     map.events.triggerEvent("moveend");
 
  40     if (browseMode == "auto") {
 
  41       if (map.getZoom() >= 15) {
 
  44           setStatus("Zoom in or select an area of the map to view");
 
  49   function stopBrowse() {
 
  53       if (browseDataLayer) {
 
  54         browseDataLayer.destroy();
 
  55         browseDataLayer = null; 
 
  58       if (browseSelectControl) {   
 
  59         browseSelectControl.destroy();  
 
  60         browseSelectControl = null;
 
  63       if (browseBoxControl) {
 
  64         browseBoxControl.destroy();
 
  65         browseBoxControl = null;
 
  68       if (browseActiveFeature) {
 
  69         browseActiveFeature.destroy(); 
 
  70         browseActiveFeature = null; 
 
  73       map.dataLayer.setVisibility(false);
 
  74       map.events.unregister("moveend", map, showData);
 
  78   function startDrag() {
 
  79     $("browse_select_box").innerHTML='Drag a box on the map to select an area';
 
  81     browseBoxControl.activate();
 
  86   $("browse_select_box").onclick = startDrag;
 
  89     var bounds = map.getExtent();
 
  90     var projected = bounds.clone().transform(map.getProjectionObject(), epsg4326);
 
  92     if (!browseBounds || !browseBounds.containsBounds(projected)) {
 
  93       var center = bounds.getCenterLonLat();
 
  94       var tileWidth = bounds.getWidth() * 1.2;
 
  95       var tileHeight = bounds.getHeight() * 1.2;
 
  96       var tileBounds = new OpenLayers.Bounds(center.lon - (tileWidth / 2),
 
  97                                              center.lat - (tileHeight / 2),
 
  98                                              center.lon + (tileWidth / 2),
 
  99                                              center.lat + (tileHeight / 2));
 
 101       browseBounds = tileBounds;
 
 106       $("browse_select_view").style.display = "none";
 
 112   $("browse_select_view").onclick = useMap;
 
 114   function endDrag(bbox) {
 
 115     var bounds = bbox.getBounds();
 
 116     var projected = bounds.clone().transform(map.getProjectionObject(), epsg4326);
 
 118     browseBoxControl.deactivate();
 
 119     browseBounds = projected;
 
 122     browseMode = "manual";  
 
 124     $("browse_select_box").innerHTML = "Manually select a different area";
 
 125     $("browse_select_view").style.display = "inline";
 
 128   function displayFeatureWarning() {
 
 131     var div = document.createElement("div");
 
 133     var p = document.createElement("p");
 
 134     p.appendChild(document.createTextNode("You have loaded an area which contains " + browseFeatureList.length + " features. In general, some browsers may not cope well with displaying this quantity of data. Generally, browsers work best at displaying less than 100 features at a time: doing anything else may make your browser slow/unresponsive. If you are sure you want to display this data, you may do so by clicking the button below."));
 
 137     var input = document.createElement("input");
 
 138     input.type = "submit";
 
 139     input.value = "Load Data";
 
 140     input.onclick = loadFeatureList;
 
 141     div.appendChild(input); 
 
 143     $("browse_content").innerHTML = "";
 
 144     $("browse_content").appendChild(div);
 
 147   function loadFeatureList() {
 
 148     browseDataLayer.addFeatures(browseFeatureList);
 
 149     browseDataLayer.events.triggerEvent("loadend");
 
 151     browseFeatureList = []; 
 
 156   function customDataLoader(request) { 
 
 158       var doc = request.responseXML;
 
 160       if (!doc || !doc.documentElement) {
 
 161         doc = request.responseText;
 
 166       OpenLayers.Util.extend(options, this.formatOptions);
 
 168       if (this.map && !this.projection.equals(this.map.getProjectionObject())) {
 
 169         options.externalProjection = this.projection;
 
 170         options.internalProjection = this.map.getProjectionObject();
 
 173       var gml = this.format ? new this.format(options) : new OpenLayers.Format.GML(options);
 
 175       browseFeatureList = gml.read(doc);
 
 177       if (!this.maxFeatures || browseFeatureList.length <= this.maxFeatures) {
 
 180         displayFeatureWarning();
 
 185   function getData(bounds) {
 
 186     var projected = bounds.clone().transform(new OpenLayers.Projection("EPSG:900913"), new OpenLayers.Projection("EPSG:4326"));
 
 187     var size = projected.getWidth() * projected.getHeight();
 
 190       setStatus("Unable to load: Bounding box size of " + size + " is too large (must be smaller than 0.25)");
 
 192       loadGML("/api/0.5/map?bbox=" + projected.toBBOX());
 
 196   function loadGML(url) {
 
 197     setStatus("Loading...");
 
 198     $("browse_content").innerHTML = "";
 
 200     if (!browseDataLayer) {
 
 201       var style = new OpenLayers.Style();
 
 203       style.addRules([new OpenLayers.Rule({
 
 205           Polygon: { fillColor: '#ff0000', strokeColor: '#ff0000' },
 
 206           Line: { fillColor: '#ffff00', strokeColor: '#000000', strokeOpacity: '0.4' },
 
 207           Point: { fillColor: '#00ff00', strokeColor: '#00ff00' }
 
 211       browseDataLayer = new OpenLayers.Layer.GML("Data", url, {
 
 212         format: OpenLayers.Format.OSM,
 
 213         formatOptions: { checkTags: true },
 
 215         requestSuccess: customDataLoader,
 
 216         displayInLayerSwitcher: false,
 
 217         styleMap: new OpenLayers.StyleMap({
 
 219           'select': { strokeColor: '#0000ff', strokeWidth: 8 }
 
 222       browseDataLayer.events.register("loadend", browseDataLayer, dataLoaded );
 
 223       map.addLayer(browseDataLayer);
 
 225       browseSelectControl = new OpenLayers.Control.SelectFeature(browseDataLayer, { onSelect: onFeatureSelect });
 
 226       browseSelectControl.handler.stopDown = false;
 
 227       browseSelectControl.handler.stopUp = false;
 
 228       map.addControl(browseSelectControl);
 
 229       browseSelectControl.activate();
 
 231       browseDataLayer.setUrl(url);
 
 234     browseActiveFeature = null;
 
 237   function dataLoaded() {
 
 241       browseObjectList = document.createElement("div")
 
 243       var heading = document.createElement("p");
 
 244       heading.className = "browse_heading";
 
 245       heading.appendChild(document.createTextNode("Object list"));
 
 246       browseObjectList.appendChild(heading);
 
 248       var list = document.createElement("ul");
 
 250       for (var i = 0; i < this.features.length; i++) {
 
 251         var feature = this.features[i]; 
 
 254         var type = featureType(feature);
 
 255         var typeName = ucFirst(type);
 
 256         var li = document.createElement("li");
 
 257         li.appendChild(document.createTextNode(typeName + " "));
 
 259         // Link, for viewing in the tab
 
 260         var link = document.createElement("a");
 
 261         link.href =  "/browse/" + type + "/" + feature.osm_id; 
 
 262         var name = feature.attributes.name || feature.osm_id;
 
 263         link.appendChild(document.createTextNode(name));
 
 264         link.feature = feature;
 
 265         link.onclick = OpenLayers.Function.bind(viewFeatureLink, link);   
 
 266         li.appendChild(link);
 
 268         list.appendChild(li);
 
 271       browseObjectList.appendChild(list)
 
 273       var link = document.createElement("a");
 
 274       link.href = this.url;
 
 275       link.appendChild(document.createTextNode("API"));
 
 276       browseObjectList.appendChild(link);
 
 278       $("browse_content").innerHTML = "";
 
 279       $("browse_content").appendChild(browseObjectList); 
 
 283   function viewFeatureLink() {
 
 284     var layer = this.feature.layer;
 
 286     for (var i = 0; i < layer.selectedFeatures.length; i++) {
 
 287       var f = layer.selectedFeatures[i]; 
 
 288       layer.drawFeature(f, layer.styleMap.createSymbolizer(f, "default"));
 
 291     onFeatureSelect(this.feature);
 
 293     if (browseMode != "auto") {
 
 294       map.setCenter(this.feature.geometry.getBounds().getCenterLonLat()); 
 
 300   function loadObjectList() {
 
 301     $("browse_content").innerHTML="";
 
 302     $("browse_content").appendChild(browseObjectList);
 
 307   function onFeatureSelect(feature) {
 
 308     // Unselect previously selected feature
 
 309     if (browseActiveFeature) {
 
 310       browseActiveFeature.layer.drawFeature(
 
 312         browseActiveFeature.layer.styleMap.createSymbolizer(browseActiveFeature, "default")
 
 316     // Redraw in selected style
 
 317     feature.layer.drawFeature(
 
 318       feature, feature.layer.styleMap.createSymbolizer(feature, "select")
 
 321     // If the current object is the list, don't innerHTML="", since that could clear it.
 
 322     if ($("browse_content").firstChild == browseObjectList) { 
 
 323       $("browse_content").removeChild(browseObjectList);
 
 325       $("browse_content").innerHTML = "";
 
 328     // Create a link back to the object list
 
 329     var div = document.createElement("div");
 
 330     div.style.textAlign = "center";
 
 331     div.style.marginBottom = "20px";
 
 332     $("browse_content").appendChild(div);
 
 333     var link = document.createElement("a");
 
 335     link.onclick = loadObjectList;
 
 336     link.appendChild(document.createTextNode("Display object list"));
 
 337     div.appendChild(link);
 
 339     var table = document.createElement("table");
 
 340     table.width = "100%";
 
 341     table.className = "browse_heading";
 
 342     $("browse_content").appendChild(table);
 
 344     var tr = document.createElement("tr");
 
 345     table.appendChild(tr);
 
 347     var heading = document.createElement("td");
 
 348     heading.appendChild(document.createTextNode(featureName(feature)));
 
 349     tr.appendChild(heading);
 
 351     var td = document.createElement("td");
 
 355     var type = featureType(feature);
 
 356     var link = document.createElement("a");   
 
 357     link.href = "/browse/" + type + "/" + feature.osm_id;
 
 358     link.appendChild(document.createTextNode("Details"));
 
 359     td.appendChild(link);
 
 361     var div = document.createElement("div");
 
 362     div.className = "browse_details";
 
 364     $("browse_content").appendChild(div);
 
 366     // Now the list of attributes
 
 367     var ul = document.createElement("ul");
 
 368     for (var key in feature.attributes) {
 
 369       var li = document.createElement("li");
 
 370       var b = document.createElement("b");
 
 371       b.appendChild(document.createTextNode(key));
 
 373       li.appendChild(document.createTextNode(": " + feature.attributes[key]));
 
 379     var link = document.createElement("a");   
 
 380     link.href =  "/browse/" + type + "/" + feature.osm_id + "/history";
 
 381     link.appendChild(document.createTextNode("Show history"));
 
 382     link.onclick = OpenLayers.Function.bind(loadHistory, {
 
 383       type: type, feature: feature, link: link
 
 386     div.appendChild(link);
 
 388     // Stash the currently drawn feature
 
 389     browseActiveFeature = feature; 
 
 392   function loadHistory() {
 
 394     this.link.innerHTML = "Wait...";
 
 396     new Ajax.Request("/api/0.5/" + this.type + "/" + this.feature.osm_id + "/history", {
 
 397       onComplete: OpenLayers.Function.bind(displayHistory, this)
 
 403   function displayHistory(request) {
 
 404     if (browseActiveFeature.osm_id != this.feature.osm_id || $("browse_content").firstChild == browseObjectList)  { 
 
 408     this.link.parentNode.removeChild(this.link);
 
 410     var doc = request.responseXML;
 
 412     var table = document.createElement("table");
 
 413     table.width = "100%";
 
 414     table.className = "browse_heading";
 
 415     $("browse_content").appendChild(table);
 
 417     var tr = document.createElement("tr");
 
 418     table.appendChild(tr);
 
 420     var heading = document.createElement("td");
 
 421     heading.appendChild(document.createTextNode("History for " + featureName(this.feature)));
 
 422     tr.appendChild(heading);
 
 424     var td = document.createElement("td");
 
 428     var link = document.createElement("a");   
 
 429     link.href = "/browse/" + this.type + "/" + this.feature.osm_id + "/history";
 
 430     link.appendChild(document.createTextNode("Details"));
 
 431     td.appendChild(link);
 
 433     var div = document.createElement("div");
 
 434     div.className = "browse_details";
 
 436     var nodes = doc.getElementsByTagName(this.type);
 
 437     var history = document.createElement("ul");  
 
 438     for (var i = nodes.length - 1; i >= 0; i--) {
 
 439       var user = nodes[i].getAttribute("user") || "private user";
 
 440       var timestamp = nodes[i].getAttribute("timestamp");
 
 441       var item = document.createElement("li");
 
 442       item.appendChild(document.createTextNode("Edited by " + user + " at " + timestamp));
 
 443       history.appendChild(item);
 
 445     div.appendChild(history);
 
 447     $("browse_content").appendChild(div); 
 
 450   function featureType(feature) {
 
 451     if (feature.geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
 
 458   function featureName(feature) {
 
 459     if (feature.attributes.name) {
 
 460       return feature.attributes.name;
 
 462       return ucFirst(featureType(feature)) + " " + feature.osm_id;
 
 466   function setStatus(status) {
 
 467     $("browse_status").innerHTML = status;
 
 468     $("browse_status").style.display = "block";
 
 471   function clearStatus() {
 
 472     $("browse_status").innerHTML = "";
 
 473     $("browse_status").style.display = "none";
 
 476   function ucFirst(str) {
 
 477     return str.substr(0,1).toUpperCase() + str.substr(1,str.length);