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();
229 * Modern browsers are quite happy showing far more than 100 features in
230 * the data browser, so increase the limit to 2000 by default, but keep
231 * it restricted to 500 for IE8 and 100 for older IEs.
233 var maxFeatures = 2000;
236 if (navigator.appVersion < 8) {
238 } else if (navigator.appVersion < 9) {
243 browseDataLayer = new OpenLayers.Layer.Vector("Data", {
245 new OpenLayers.Strategy.Fixed()
247 protocol: new OpenLayers.Protocol.HTTP({
249 format: new OpenLayers.Format.OSM(formatOptions),
250 maxFeatures: maxFeatures,
251 handleRead: customDataLoader
253 projection: new OpenLayers.Projection("EPSG:4326"),
254 displayInLayerSwitcher: false,
255 styleMap: new OpenLayers.StyleMap({
257 'select': { strokeColor: '#0000ff', strokeWidth: 8 }
260 browseDataLayer.events.register("loadend", browseDataLayer, dataLoaded );
261 map.addLayer(browseDataLayer);
263 browseSelectControl = new OpenLayers.Control.SelectFeature(browseDataLayer, { onSelect: onFeatureSelect });
264 browseSelectControl.handlers.feature.stopDown = false;
265 browseSelectControl.handlers.feature.stopUp = false;
266 map.addControl(browseSelectControl);
267 browseSelectControl.activate();
269 browseDataLayer.destroyFeatures();
270 browseDataLayer.refresh({ url: url });
273 browseActiveFeature = null;
276 function dataLoaded() {
277 if (this.map.dataLayer.active) {
280 browseObjectList = document.createElement("div");
282 var heading = document.createElement("p");
283 heading.className = "browse_heading";
284 heading.appendChild(document.createTextNode(I18n.t('browse.start_rjs.object_list.heading')));
285 browseObjectList.appendChild(heading);
287 var list = document.createElement("ul");
289 for (var i = 0; i < this.features.length; i++) {
290 var feature = this.features[i];
293 var type = featureType(feature);
294 var typeName = featureTypeName(feature);
295 var li = document.createElement("li");
296 li.appendChild(document.createTextNode(typeName + " "));
298 // Link, for viewing in the tab
299 var link = document.createElement("a");
300 link.href = "/browse/" + type + "/" + feature.osm_id;
301 var name = featureName(feature);
302 link.appendChild(document.createTextNode(name));
303 link.feature = feature;
304 link.onclick = OpenLayers.Function.bind(viewFeatureLink, link);
305 li.appendChild(link);
307 list.appendChild(li);
310 browseObjectList.appendChild(list);
312 var link = document.createElement("a");
313 link.href = this.protocol.url;
314 link.appendChild(document.createTextNode(I18n.t('browse.start_rjs.object_list.api')));
315 browseObjectList.appendChild(link);
317 $("#browse_content").html(browseObjectList);
321 function viewFeatureLink() {
322 var layer = this.feature.layer;
324 for (var i = 0; i < layer.selectedFeatures.length; i++) {
325 var f = layer.selectedFeatures[i];
326 layer.drawFeature(f, layer.styleMap.createSymbolizer(f, "default"));
329 onFeatureSelect(this.feature);
331 if (browseMode != "auto") {
332 map.setCenter(this.feature.geometry.getBounds().getCenterLonLat());
338 function loadObjectList() {
339 $("#browse_content").empty();
340 $("#browse_content").append(browseObjectList);
345 function onFeatureSelect(feature) {
346 // Unselect previously selected feature
347 if (browseActiveFeature) {
348 browseActiveFeature.layer.drawFeature(
350 browseActiveFeature.layer.styleMap.createSymbolizer(browseActiveFeature, "default")
354 // Redraw in selected style
355 feature.layer.drawFeature(
356 feature, feature.layer.styleMap.createSymbolizer(feature, "select")
359 // If the current object is the list, don't innerHTML="", since that could clear it.
360 if ($("#browse_content").firstChild == browseObjectList) {
361 $("#browse_content").removeChild(browseObjectList);
363 $("#browse_content").empty();
366 // Create a link back to the object list
367 var div = document.createElement("div");
368 div.style.textAlign = "center";
369 div.style.marginBottom = "20px";
370 $("#browse_content").append(div);
371 var link = document.createElement("a");
373 link.onclick = loadObjectList;
374 link.appendChild(document.createTextNode(I18n.t('browse.start_rjs.object_list.back')));
375 div.appendChild(link);
377 var table = document.createElement("table");
378 table.width = "100%";
379 table.className = "browse_heading";
380 $("#browse_content").append(table);
382 var tr = document.createElement("tr");
383 table.appendChild(tr);
385 var heading = document.createElement("td");
386 heading.appendChild(document.createTextNode(featureNameSelect(feature)));
387 tr.appendChild(heading);
389 var td = document.createElement("td");
393 var type = featureType(feature);
394 var link = document.createElement("a");
395 link.href = "/browse/" + type + "/" + feature.osm_id;
396 link.appendChild(document.createTextNode(I18n.t('browse.start_rjs.object_list.details')));
397 td.appendChild(link);
399 var div = document.createElement("div");
400 div.className = "browse_details";
402 $("#browse_content").append(div);
404 // Now the list of attributes
405 var ul = document.createElement("ul");
406 for (var key in feature.attributes) {
407 var li = document.createElement("li");
408 var b = document.createElement("b");
409 b.appendChild(document.createTextNode(key));
411 li.appendChild(document.createTextNode(": " + feature.attributes[key]));
417 var link = document.createElement("a");
418 link.href = "/browse/" + type + "/" + feature.osm_id + "/history";
419 link.appendChild(document.createTextNode(I18n.t('browse.start_rjs.show_history')));
420 link.onclick = OpenLayers.Function.bind(loadHistory, {
421 type: type, feature: feature, link: link
424 div.appendChild(link);
426 // Stash the currently drawn feature
427 browseActiveFeature = feature;
430 function loadHistory() {
432 this.link.innerHTML = I18n.t('browse.start_rjs.wait');
434 $.ajax("/api/" + OSM.API_VERSION + "/" + this.type + "/" + this.feature.osm_id + "/history", {
435 complete: OpenLayers.Function.bind(displayHistory, this)
441 function displayHistory(request) {
442 if (browseActiveFeature.osm_id != this.feature.osm_id || $("#browse_content").firstChild == browseObjectList) {
446 this.link.parentNode.removeChild(this.link);
448 var doc = request.responseXML;
450 var table = document.createElement("table");
451 table.width = "100%";
452 table.className = "browse_heading";
453 $("#browse_content").append(table);
455 var tr = document.createElement("tr");
456 table.appendChild(tr);
458 var heading = document.createElement("td");
459 heading.appendChild(document.createTextNode(I18n.t("browse.start_rjs.history_for_feature", { feature: featureNameHistory(this.feature) })));
460 tr.appendChild(heading);
462 var td = document.createElement("td");
466 var link = document.createElement("a");
467 link.href = "/browse/" + this.type + "/" + this.feature.osm_id + "/history";
468 link.appendChild(document.createTextNode(I18n.t('browse.start_rjs.details')));
469 td.appendChild(link);
471 var div = document.createElement("div");
472 div.className = "browse_details";
474 var nodes = doc.getElementsByTagName(this.type);
475 var history = document.createElement("ul");
476 for (var i = nodes.length - 1; i >= 0; i--) {
477 var user = nodes[i].getAttribute("user") || I18n.t('browse.start_rjs.private_user');
478 var timestamp = nodes[i].getAttribute("timestamp");
479 var item = document.createElement("li");
480 item.appendChild(document.createTextNode(I18n.t("browse.start_rjs.edited_by_user_at_timestamp", { user: user, timestamp: timestamp })));
481 history.appendChild(item);
483 div.appendChild(history);
485 $("#browse_content").append(div);
488 function featureType(feature) {
489 if (feature.geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
496 function featureTypeName(feature) {
497 if (featureType(feature) == "node") {
498 return I18n.t('browse.start_rjs.object_list.type.node');
499 } else if (featureType(feature) == "way") {
500 return I18n.t('browse.start_rjs.object_list.type.way');
504 function featureName(feature) {
505 var lang = $('html').attr('lang');
506 if (feature.attributes['name:' + lang]) {
507 return feature.attributes['name:' + lang];
508 } else if (feature.attributes.name) {
509 return feature.attributes.name;
511 return feature.osm_id;
515 function featureNameSelect(feature) {
516 var lang = $('html').attr('lang');
517 if (feature.attributes['name:' + lang]) {
518 return feature.attributes['name:' + lang];
519 } else if (feature.attributes.name) {
520 return feature.attributes.name;
521 } else if (featureType(feature) == "node") {
522 return I18n.t("browse.start_rjs.object_list.selected.type.node", { id: feature.osm_id });
523 } else if (featureType(feature) == "way") {
524 return I18n.t("browse.start_rjs.object_list.selected.type.way", { id: feature.osm_id });
528 function featureNameHistory(feature) {
529 var lang = $('html').attr('lang');
530 if (feature.attributes['name:' + lang]) {
531 return feature.attributes['name:' + lang];
532 } else if (feature.attributes.name) {
533 return feature.attributes.name;
534 } else if (featureType(feature) == "node") {
535 return I18n.t("browse.start_rjs.object_list.history.type.node", { id: feature.osm_id });
536 } else if (featureType(feature) == "way") {
537 return I18n.t("browse.start_rjs.object_list.history.type.way", { id: feature.osm_id });
541 function setStatus(status) {
542 $("#browse_status").html(status);
543 $("#browse_status").show();
546 function clearStatus() {
547 $("#browse_status").html("");
548 $("#browse_status").hide();