page.replace_html :sidebar_title, 'Data' page.replace_html :sidebar_content, :partial => 'start' page << <= 15) { useMap(); } else { setStatus("Zoom in or select an area of the map to view"); } } } function stopBrowse() { if (browseActive) { browseActive = false; if (browseDataLayer) { browseDataLayer.destroy(); browseDataLayer = null; } if (browseSelectControl) { browseSelectControl.destroy(); browseSelectControl = null; } if (browseBoxControl) { browseBoxControl.destroy(); browseBoxControl = null; } if (browseActiveFeature) { browseActiveFeature.destroy(); browseActiveFeature = null; } map.dataLayer.setVisibility(false); map.events.unregister("moveend", map, showData); } } function startDrag() { $("browse_select_box").innerHTML='Drag a box on the map to select an area'; browseBoxControl.activate(); return false; }; $("browse_select_box").onclick = startDrag; function useMap() { var bounds = map.getExtent(); var projected = bounds.clone().transform(map.getProjectionObject(), epsg4326); if (!browseBounds || !browseBounds.containsBounds(projected)) { var center = bounds.getCenterLonLat(); var tileWidth = bounds.getWidth() * 1.2; var tileHeight = bounds.getHeight() * 1.2; var tileBounds = new OpenLayers.Bounds(center.lon - (tileWidth / 2), center.lat - (tileHeight / 2), center.lon + (tileWidth / 2), center.lat + (tileHeight / 2)); browseBounds = tileBounds; getData(tileBounds); browseMode = "auto"; $("browse_select_view").style.display = "none"; } return false; } $("browse_select_view").onclick = useMap; function endDrag(bbox) { var bounds = bbox.getBounds(); var projected = bounds.clone().transform(map.getProjectionObject(), epsg4326); browseBoxControl.deactivate(); browseBounds = projected; getData(bounds); browseMode = "manual"; $("browse_select_box").innerHTML = "Manually select a different area"; $("browse_select_view").style.display = "inline"; } function displayFeatureWarning() { clearStatus(); var div = document.createElement("div"); var p = document.createElement("p"); 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.")); div.appendChild(p); var input = document.createElement("input"); input.type = "submit"; input.value = "Load Data"; input.onclick = loadFeatureList; div.appendChild(input); $("browse_content").innerHTML = ""; $("browse_content").appendChild(div); } function loadFeatureList() { browseDataLayer.addFeatures(browseFeatureList); browseDataLayer.events.triggerEvent("loadend"); browseFeatureList = []; return false; } function customDataLoader(request) { if (browseActive) { var doc = request.responseXML; if (!doc || !doc.documentElement) { doc = request.responseText; } var options = {}; OpenLayers.Util.extend(options, this.formatOptions); if (this.map && !this.projection.equals(this.map.getProjectionObject())) { options.externalProjection = this.projection; options.internalProjection = this.map.getProjectionObject(); } var gml = this.format ? new this.format(options) : new OpenLayers.Format.GML(options); browseFeatureList = gml.read(doc); if (!this.maxFeatures || browseFeatureList.length <= this.maxFeatures) { loadFeatureList(); } else { displayFeatureWarning(); } } } function getData(bounds) { var projected = bounds.clone().transform(new OpenLayers.Projection("EPSG:900913"), new OpenLayers.Projection("EPSG:4326")); var size = projected.getWidth() * projected.getHeight(); if (size > 0.25) { setStatus("Unable to load: Bounding box size of " + size + " is too large (must be smaller than 0.25)"); } else { loadGML("/api/#{API_VERSION}/map?bbox=" + projected.toBBOX()); } } function loadGML(url) { setStatus("Loading..."); $("browse_content").innerHTML = ""; if (!browseDataLayer) { var style = new OpenLayers.Style(); style.addRules([new OpenLayers.Rule({ symbolizer: { Polygon: { fillColor: '#ff0000', strokeColor: '#ff0000' }, Line: { fillColor: '#ffff00', strokeColor: '#000000', strokeOpacity: '0.4' }, Point: { fillColor: '#00ff00', strokeColor: '#00ff00' } } })]); browseDataLayer = new OpenLayers.Layer.GML("Data", url, { format: OpenLayers.Format.OSM, formatOptions: { checkTags: true }, maxFeatures: 100, requestSuccess: customDataLoader, displayInLayerSwitcher: false, styleMap: new OpenLayers.StyleMap({ 'default': style, 'select': { strokeColor: '#0000ff', strokeWidth: 8 } }) }); browseDataLayer.events.register("loadend", browseDataLayer, dataLoaded ); map.addLayer(browseDataLayer); browseSelectControl = new OpenLayers.Control.SelectFeature(browseDataLayer, { onSelect: onFeatureSelect }); browseSelectControl.handlers.feature.stopDown = false; browseSelectControl.handlers.feature.stopUp = false; map.addControl(browseSelectControl); browseSelectControl.activate(); } else { browseDataLayer.setUrl(url); } browseActiveFeature = null; } function dataLoaded() { if (browseActive) { clearStatus(); browseObjectList = document.createElement("div") var heading = document.createElement("p"); heading.className = "browse_heading"; heading.appendChild(document.createTextNode("Object list")); browseObjectList.appendChild(heading); var list = document.createElement("ul"); for (var i = 0; i < this.features.length; i++) { var feature = this.features[i]; // Type, for linking var type = featureType(feature); var typeName = ucFirst(type); var li = document.createElement("li"); li.appendChild(document.createTextNode(typeName + " ")); // Link, for viewing in the tab var link = document.createElement("a"); link.href = "/browse/" + type + "/" + feature.osm_id; var name = feature.attributes.name || feature.osm_id; link.appendChild(document.createTextNode(name)); link.feature = feature; link.onclick = OpenLayers.Function.bind(viewFeatureLink, link); li.appendChild(link); list.appendChild(li); } browseObjectList.appendChild(list) var link = document.createElement("a"); link.href = this.url; link.appendChild(document.createTextNode("API")); browseObjectList.appendChild(link); $("browse_content").innerHTML = ""; $("browse_content").appendChild(browseObjectList); } } function viewFeatureLink() { var layer = this.feature.layer; for (var i = 0; i < layer.selectedFeatures.length; i++) { var f = layer.selectedFeatures[i]; layer.drawFeature(f, layer.styleMap.createSymbolizer(f, "default")); } onFeatureSelect(this.feature); if (browseMode != "auto") { map.setCenter(this.feature.geometry.getBounds().getCenterLonLat()); } return false; } function loadObjectList() { $("browse_content").innerHTML=""; $("browse_content").appendChild(browseObjectList); return false; } function onFeatureSelect(feature) { // Unselect previously selected feature if (browseActiveFeature) { browseActiveFeature.layer.drawFeature( browseActiveFeature, browseActiveFeature.layer.styleMap.createSymbolizer(browseActiveFeature, "default") ); } // Redraw in selected style feature.layer.drawFeature( feature, feature.layer.styleMap.createSymbolizer(feature, "select") ); // If the current object is the list, don't innerHTML="", since that could clear it. if ($("browse_content").firstChild == browseObjectList) { $("browse_content").removeChild(browseObjectList); } else { $("browse_content").innerHTML = ""; } // Create a link back to the object list var div = document.createElement("div"); div.style.textAlign = "center"; div.style.marginBottom = "20px"; $("browse_content").appendChild(div); var link = document.createElement("a"); link.href = "#"; link.onclick = loadObjectList; link.appendChild(document.createTextNode("Display object list")); div.appendChild(link); var table = document.createElement("table"); table.width = "100%"; table.className = "browse_heading"; $("browse_content").appendChild(table); var tr = document.createElement("tr"); table.appendChild(tr); var heading = document.createElement("td"); heading.appendChild(document.createTextNode(featureName(feature))); tr.appendChild(heading); var td = document.createElement("td"); td.align = "right"; tr.appendChild(td); var type = featureType(feature); var link = document.createElement("a"); link.href = "/browse/" + type + "/" + feature.osm_id; link.appendChild(document.createTextNode("Details")); td.appendChild(link); var div = document.createElement("div"); div.className = "browse_details"; $("browse_content").appendChild(div); // Now the list of attributes var ul = document.createElement("ul"); for (var key in feature.attributes) { var li = document.createElement("li"); var b = document.createElement("b"); b.appendChild(document.createTextNode(key)); li.appendChild(b); li.appendChild(document.createTextNode(": " + feature.attributes[key])); ul.appendChild(li); } div.appendChild(ul); var link = document.createElement("a"); link.href = "/browse/" + type + "/" + feature.osm_id + "/history"; link.appendChild(document.createTextNode("Show history")); link.onclick = OpenLayers.Function.bind(loadHistory, { type: type, feature: feature, link: link }); div.appendChild(link); // Stash the currently drawn feature browseActiveFeature = feature; } function loadHistory() { this.link.href = ""; this.link.innerHTML = "Wait..."; new Ajax.Request("/api/#{API_VERSION}/" + this.type + "/" + this.feature.osm_id + "/history", { onComplete: OpenLayers.Function.bind(displayHistory, this) }); return false; } function displayHistory(request) { if (browseActiveFeature.osm_id != this.feature.osm_id || $("browse_content").firstChild == browseObjectList) { return false; } this.link.parentNode.removeChild(this.link); var doc = request.responseXML; var table = document.createElement("table"); table.width = "100%"; table.className = "browse_heading"; $("browse_content").appendChild(table); var tr = document.createElement("tr"); table.appendChild(tr); var heading = document.createElement("td"); heading.appendChild(document.createTextNode("History for " + featureName(this.feature))); tr.appendChild(heading); var td = document.createElement("td"); td.align = "right"; tr.appendChild(td); var link = document.createElement("a"); link.href = "/browse/" + this.type + "/" + this.feature.osm_id + "/history"; link.appendChild(document.createTextNode("Details")); td.appendChild(link); var div = document.createElement("div"); div.className = "browse_details"; var nodes = doc.getElementsByTagName(this.type); var history = document.createElement("ul"); for (var i = nodes.length - 1; i >= 0; i--) { var user = nodes[i].getAttribute("user") || "private user"; var timestamp = nodes[i].getAttribute("timestamp"); var item = document.createElement("li"); item.appendChild(document.createTextNode("Edited by " + user + " at " + timestamp)); history.appendChild(item); } div.appendChild(history); $("browse_content").appendChild(div); } function featureType(feature) { if (feature.geometry.CLASS_NAME == "OpenLayers.Geometry.Point") { return "node"; } else { return "way"; } } function featureName(feature) { if (feature.attributes.name) { return feature.attributes.name; } else { return ucFirst(featureType(feature)) + " " + feature.osm_id; } } function setStatus(status) { $("browse_status").innerHTML = status; $("browse_status").style.display = "block"; } function clearStatus() { $("browse_status").innerHTML = ""; $("browse_status").style.display = "none"; } function ucFirst(str) { return str.substr(0,1).toUpperCase() + str.substr(1,str.length); } startBrowse(); EOJ