2 var browseMode = "auto";
5 var browseActiveFeature;
7 var browseSelectControl;
9 var areasHidden = false;
11 OpenLayers.Feature.Vector.style['default'].strokeWidth = 3;
12 OpenLayers.Feature.Vector.style['default'].cursor = "pointer";
14 function startBrowse(sidebarHtml) {
15 map.dataLayer.active = true;
17 $("#sidebar_title").html(I18n.t('browse.start_rjs.data_frame_title'));
18 $("#sidebar_content").html(sidebarHtml);
20 openSidebar({ onclose: stopBrowse });
22 var vectors = new OpenLayers.Layer.Vector();
24 browseBoxControl = new OpenLayers.Control.DrawFeature(vectors, OpenLayers.Handler.RegularPolygon, {
32 browseBoxControl.handler.callbacks.done = endDrag;
33 map.addControl(browseBoxControl);
35 map.events.register("moveend", map, updateData);
36 map.events.triggerEvent("moveend");
38 $("#browse_select_view").click(useMap);
40 $("#browse_select_box").click(startDrag);
42 $("#browse_hide_areas_box").html(I18n.t('browse.start_rjs.hide_areas'));
43 $("#browse_hide_areas_box").show();
44 $("#browse_hide_areas_box").click(hideAreas);
47 function updateData() {
48 if (browseMode == "auto") {
49 if (map.getZoom() >= 15) {
52 setStatus(I18n.t('browse.start_rjs.zoom_or_select'));
57 function stopBrowse() {
58 if (map.dataLayer.active) {
59 map.dataLayer.active = false;
61 if (browseSelectControl) {
62 browseSelectControl.destroy();
63 browseSelectControl = null;
66 if (browseBoxControl) {
67 browseBoxControl.destroy();
68 browseBoxControl = null;
71 if (browseActiveFeature) {
72 browseActiveFeature.destroy();
73 browseActiveFeature = null;
76 if (browseDataLayer) {
77 browseDataLayer.destroy();
78 browseDataLayer = null;
81 map.dataLayer.setVisibility(false);
82 map.events.unregister("moveend", map, updateData);
86 function startDrag() {
87 $("#browse_select_box").html(I18n.t('browse.start_rjs.drag_a_box'));
89 browseBoxControl.activate();
94 function useMap(reload) {
95 var bounds = map.getExtent();
96 var projected = bounds.clone().transform(map.getProjectionObject(), epsg4326);
98 if (!browseBounds || !browseBounds.containsBounds(projected)) {
99 var center = bounds.getCenterLonLat();
100 var tileWidth = bounds.getWidth() * 1.2;
101 var tileHeight = bounds.getHeight() * 1.2;
102 var tileBounds = new OpenLayers.Bounds(center.lon - (tileWidth / 2),
103 center.lat - (tileHeight / 2),
104 center.lon + (tileWidth / 2),
105 center.lat + (tileHeight / 2));
107 browseBounds = tileBounds;
108 getData(tileBounds, reload);
112 $("#browse_select_view").hide();
118 function hideAreas() {
119 $("#browse_hide_areas_box").html(I18n.t('browse.start_rjs.show_areas'));
120 $("#browse_hide_areas_box").show();
121 $("#browse_hide_areas_box").click(showAreas);
128 function showAreas() {
129 $("#browse_hide_areas_box").html(I18n.t('browse.start_rjs.hide_areas'));
130 $("#browse_hide_areas_box").show();
131 $("#browse_hide_areas_box").click(hideAreas);
138 function endDrag(bbox) {
139 var bounds = bbox.getBounds();
140 var projected = bounds.clone().transform(map.getProjectionObject(), epsg4326);
142 browseBoxControl.deactivate();
143 browseBounds = projected;
146 browseMode = "manual";
148 $("#browse_select_box").html(I18n.t('browse.start_rjs.manually_select'));
149 $("#browse_select_view").show();
152 function displayFeatureWarning(count, limit, callback) {
155 var div = document.createElement("div");
157 var p = document.createElement("p");
158 p.appendChild(document.createTextNode(I18n.t("browse.start_rjs.loaded_an_area_with_num_features", { num_features: count, max_features: limit })));
161 var input = document.createElement("input");
162 input.type = "submit";
163 input.value = I18n.t('browse.start_rjs.load_data');
164 input.onclick = callback;
165 div.appendChild(input);
167 $("#browse_content").html("");
168 $("#browse_content").append(div);
171 function customDataLoader(resp, options) {
172 if (map.dataLayer.active) {
173 var request = resp.priv;
174 var doc = request.responseXML;
176 if (!doc || !doc.documentElement) {
177 doc = request.responseText;
180 resp.features = this.format.read(doc);
182 if (!this.maxFeatures || resp.features.length <= this.maxFeatures) {
183 options.callback.call(options.scope, resp);
185 displayFeatureWarning(resp.features.length, this.maxFeatures, function () {
186 options.callback.call(options.scope, resp);
192 function getData(bounds, reload) {
193 var projected = bounds.clone().transform(new OpenLayers.Projection("EPSG:900913"), new OpenLayers.Projection("EPSG:4326"));
194 var size = projected.getWidth() * projected.getHeight();
196 if (size > OSM.MAX_REQUEST_AREA) {
197 setStatus(I18n.t("browse.start_rjs.unable_to_load_size", { max_bbox_size: OSM.MAX_REQUEST_AREA, bbox_size: size }));
199 loadData("/api/" + OSM.API_VERSION + "/map?bbox=" + projected.toBBOX(), reload);
203 function loadData(url, reload) {
204 setStatus(I18n.t('browse.start_rjs.loading'));
206 $("#browse_content").empty();
208 var formatOptions = {
210 interestingTagsExclude: ['source','source_ref','source:ref','history','attribution','created_by','tiger:county','tiger:tlid','tiger:upload_uuid']
213 if (areasHidden) formatOptions.areaTags = [];
215 if (!browseDataLayer || reload) {
216 var style = new OpenLayers.Style();
218 style.addRules([new OpenLayers.Rule({
220 Polygon: { fillColor: '#ff0000', strokeColor: '#ff0000' },
221 Line: { fillColor: '#ffff00', strokeColor: '#000000', strokeOpacity: '0.4' },
222 Point: { fillColor: '#00ff00', strokeColor: '#00ff00' }
226 if (browseDataLayer) browseDataLayer.destroyFeatures();
228 var maxFeatures = 2000;
231 if (navigator.appVersion < 8) {
233 } else if (navigator.appVersion < 9) {
238 browseDataLayer = new OpenLayers.Layer.Vector("Data", {
240 new OpenLayers.Strategy.Fixed()
242 protocol: new OpenLayers.Protocol.HTTP({
244 format: new OpenLayers.Format.OSM(formatOptions),
245 maxFeatures: maxFeatures,
246 handleRead: customDataLoader
248 projection: new OpenLayers.Projection("EPSG:4326"),
249 displayInLayerSwitcher: false,
250 styleMap: new OpenLayers.StyleMap({
252 'select': { strokeColor: '#0000ff', strokeWidth: 8 }
255 browseDataLayer.events.register("loadend", browseDataLayer, dataLoaded );
256 map.addLayer(browseDataLayer);
258 browseSelectControl = new OpenLayers.Control.SelectFeature(browseDataLayer, { onSelect: onFeatureSelect });
259 browseSelectControl.handlers.feature.stopDown = false;
260 browseSelectControl.handlers.feature.stopUp = false;
261 map.addControl(browseSelectControl);
262 browseSelectControl.activate();
264 browseDataLayer.destroyFeatures();
265 browseDataLayer.refresh({ url: url });
268 browseActiveFeature = null;
271 function dataLoaded() {
272 if (this.map.dataLayer.active) {
275 browseObjectList = document.createElement("div");
277 var heading = document.createElement("p");
278 heading.className = "browse_heading";
279 heading.appendChild(document.createTextNode(I18n.t('browse.start_rjs.object_list.heading')));
280 browseObjectList.appendChild(heading);
282 var list = document.createElement("ul");
284 for (var i = 0; i < this.features.length; i++) {
285 var feature = this.features[i];
288 var type = featureType(feature);
289 var typeName = featureTypeName(feature);
290 var li = document.createElement("li");
291 li.appendChild(document.createTextNode(typeName + " "));
293 // Link, for viewing in the tab
294 var link = document.createElement("a");
295 link.href = "/browse/" + type + "/" + feature.osm_id;
296 var name = featureName(feature);
297 link.appendChild(document.createTextNode(name));
298 link.feature = feature;
299 link.onclick = OpenLayers.Function.bind(viewFeatureLink, link);
300 li.appendChild(link);
302 list.appendChild(li);
305 browseObjectList.appendChild(list);
307 var link = document.createElement("a");
308 link.href = this.protocol.url;
309 link.appendChild(document.createTextNode(I18n.t('browse.start_rjs.object_list.api')));
310 browseObjectList.appendChild(link);
312 $("#browse_content").html(browseObjectList);
316 function viewFeatureLink() {
317 var layer = this.feature.layer;
319 for (var i = 0; i < layer.selectedFeatures.length; i++) {
320 var f = layer.selectedFeatures[i];
321 layer.drawFeature(f, layer.styleMap.createSymbolizer(f, "default"));
324 onFeatureSelect(this.feature);
326 if (browseMode != "auto") {
327 map.setCenter(this.feature.geometry.getBounds().getCenterLonLat());
333 function loadObjectList() {
334 $("#browse_content").empty();
335 $("#browse_content").append(browseObjectList);
340 function onFeatureSelect(feature) {
341 // Unselect previously selected feature
342 if (browseActiveFeature) {
343 browseActiveFeature.layer.drawFeature(
345 browseActiveFeature.layer.styleMap.createSymbolizer(browseActiveFeature, "default")
349 // Redraw in selected style
350 feature.layer.drawFeature(
351 feature, feature.layer.styleMap.createSymbolizer(feature, "select")
354 // If the current object is the list, don't innerHTML="", since that could clear it.
355 if ($("#browse_content").firstChild == browseObjectList) {
356 $("#browse_content").removeChild(browseObjectList);
358 $("#browse_content").empty();
361 // Create a link back to the object list
362 var div = document.createElement("div");
363 div.style.textAlign = "center";
364 div.style.marginBottom = "20px";
365 $("#browse_content").append(div);
366 var link = document.createElement("a");
368 link.onclick = loadObjectList;
369 link.appendChild(document.createTextNode(I18n.t('browse.start_rjs.object_list.back')));
370 div.appendChild(link);
372 var table = document.createElement("table");
373 table.width = "100%";
374 table.className = "browse_heading";
375 $("#browse_content").append(table);
377 var tr = document.createElement("tr");
378 table.appendChild(tr);
380 var heading = document.createElement("td");
381 heading.appendChild(document.createTextNode(featureNameSelect(feature)));
382 tr.appendChild(heading);
384 var td = document.createElement("td");
388 var type = featureType(feature);
389 var link = document.createElement("a");
390 link.href = "/browse/" + type + "/" + feature.osm_id;
391 link.appendChild(document.createTextNode(I18n.t('browse.start_rjs.object_list.details')));
392 td.appendChild(link);
394 var div = document.createElement("div");
395 div.className = "browse_details";
397 $("#browse_content").append(div);
399 // Now the list of attributes
400 var ul = document.createElement("ul");
401 for (var key in feature.attributes) {
402 var li = document.createElement("li");
403 var b = document.createElement("b");
404 b.appendChild(document.createTextNode(key));
406 li.appendChild(document.createTextNode(": " + feature.attributes[key]));
412 var link = document.createElement("a");
413 link.href = "/browse/" + type + "/" + feature.osm_id + "/history";
414 link.appendChild(document.createTextNode(I18n.t('browse.start_rjs.show_history')));
415 link.onclick = OpenLayers.Function.bind(loadHistory, {
416 type: type, feature: feature, link: link
419 div.appendChild(link);
421 // Stash the currently drawn feature
422 browseActiveFeature = feature;
425 function loadHistory() {
427 this.link.innerHTML = I18n.t('browse.start_rjs.wait');
429 $.ajax("/api/" + OSM.API_VERSION + "/" + this.type + "/" + this.feature.osm_id + "/history", {
430 complete: OpenLayers.Function.bind(displayHistory, this)
436 function displayHistory(request) {
437 if (browseActiveFeature.osm_id != this.feature.osm_id || $("#browse_content").firstChild == browseObjectList) {
441 this.link.parentNode.removeChild(this.link);
443 var doc = request.responseXML;
445 var table = document.createElement("table");
446 table.width = "100%";
447 table.className = "browse_heading";
448 $("#browse_content").append(table);
450 var tr = document.createElement("tr");
451 table.appendChild(tr);
453 var heading = document.createElement("td");
454 heading.appendChild(document.createTextNode(I18n.t("browse.start_rjs.history_for_feature", { feature: featureNameHistory(this.feature) })));
455 tr.appendChild(heading);
457 var td = document.createElement("td");
461 var link = document.createElement("a");
462 link.href = "/browse/" + this.type + "/" + this.feature.osm_id + "/history";
463 link.appendChild(document.createTextNode(I18n.t('browse.start_rjs.details')));
464 td.appendChild(link);
466 var div = document.createElement("div");
467 div.className = "browse_details";
469 var nodes = doc.getElementsByTagName(this.type);
470 var history = document.createElement("ul");
471 for (var i = nodes.length - 1; i >= 0; i--) {
472 var user = nodes[i].getAttribute("user") || I18n.t('browse.start_rjs.private_user');
473 var timestamp = nodes[i].getAttribute("timestamp");
474 var item = document.createElement("li");
475 item.appendChild(document.createTextNode(I18n.t("browse.start_rjs.edited_by_user_at_timestamp", { user: user, timestamp: timestamp })));
476 history.appendChild(item);
478 div.appendChild(history);
480 $("#browse_content").append(div);
483 function featureType(feature) {
484 if (feature.geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
491 function featureTypeName(feature) {
492 if (featureType(feature) == "node") {
493 return I18n.t('browse.start_rjs.object_list.type.node');
494 } else if (featureType(feature) == "way") {
495 return I18n.t('browse.start_rjs.object_list.type.way');
499 function featureName(feature) {
500 var lang = $('html').attr('lang');
501 if (feature.attributes['name:' + lang]) {
502 return feature.attributes['name:' + lang];
503 } else if (feature.attributes.name) {
504 return feature.attributes.name;
506 return feature.osm_id;
510 function featureNameSelect(feature) {
511 var lang = $('html').attr('lang');
512 if (feature.attributes['name:' + lang]) {
513 return feature.attributes['name:' + lang];
514 } else if (feature.attributes.name) {
515 return feature.attributes.name;
516 } else if (featureType(feature) == "node") {
517 return I18n.t("browse.start_rjs.object_list.selected.type.node", { id: feature.osm_id });
518 } else if (featureType(feature) == "way") {
519 return I18n.t("browse.start_rjs.object_list.selected.type.way", { id: feature.osm_id });
523 function featureNameHistory(feature) {
524 var lang = $('html').attr('lang');
525 if (feature.attributes['name:' + lang]) {
526 return feature.attributes['name:' + lang];
527 } else if (feature.attributes.name) {
528 return feature.attributes.name;
529 } else if (featureType(feature) == "node") {
530 return I18n.t("browse.start_rjs.object_list.history.type.node", { id: feature.osm_id });
531 } else if (featureType(feature) == "way") {
532 return I18n.t("browse.start_rjs.object_list.history.type.way", { id: feature.osm_id });
536 function setStatus(status) {
537 $("#browse_status").html(status);
538 $("#browse_status").show();
541 function clearStatus() {
542 $("#browse_status").html("");
543 $("#browse_status").hide();
546 startBrowse("<%=j render :partial => "sidebar" %>");