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() {
20 openSidebar({ onclose: stopBrowse });
22 var vectors = new OpenLayers.Layer.Vector();
24 browseBoxControl = new OpenLayers.Control.DrawFeature(vectors, OpenLayers.Handler.RegularPolygon, {
30 callbacks: { done: endDrag }
33 map.addControl(browseBoxControl);
35 map.events.register("moveend", map, showData);
36 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 (browseSelectControl) {
54 browseSelectControl.destroy();
55 browseSelectControl = null;
58 if (browseBoxControl) {
59 browseBoxControl.destroy();
60 browseBoxControl = null;
63 if (browseActiveFeature) {
64 browseActiveFeature.destroy();
65 browseActiveFeature = null;
68 if (browseDataLayer) {
69 browseDataLayer.destroy();
70 browseDataLayer = 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/#{API_VERSION}/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.handlers.feature.stopDown = false;
227 browseSelectControl.handlers.feature.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/#{API_VERSION}/" + 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);