]> git.openstreetmap.org Git - rails.git/blob - app/assets/javascripts/index/browse.js
0016c7b5d1c0ad35af2983886649cce0f8815fd7
[rails.git] / app / assets / javascripts / index / browse.js
1 //= require templates/browse/feature
2 //= require templates/browse/feature_list
3 //= require templates/browse/feature_history
4
5 $(document).ready(function () {
6   $("#show_data").click(function (e) {
7     $.ajax({ url: $(this).attr('href'), success: function (sidebarHtml) {
8       startBrowse(sidebarHtml);
9     }});
10     e.preventDefault();
11   });
12
13   function startBrowse(sidebarHtml) {
14     var browseBounds;
15     var layersById;
16     var selectedLayer;
17     var browseObjectList;
18     var areasHidden = false;
19
20     var dataLayer = new L.OSM.DataLayer(null, {
21       styles: {
22         way: {
23           weight: 3,
24           color: "#000000",
25           opacity: 0.4
26         },
27         area: {
28           weight: 3,
29           color: "#ff0000"
30         },
31         node: {
32           color: "#00ff00"
33         }
34       }
35     });
36
37     dataLayer.addTo(map);
38
39     dataLayer.isWayArea = function () {
40       return !areasHidden && L.OSM.DataLayer.prototype.isWayArea.apply(this, arguments);
41     };
42
43     var locationFilter = new L.LocationFilter({
44       enableButton: false,
45       adjustButton: false,
46       onChange: getData
47     }).addTo(map);
48
49     $("#sidebar_title").html(I18n.t('browse.start_rjs.data_frame_title'));
50     $("#sidebar_content").html(sidebarHtml);
51
52     openSidebar();
53
54     map.on("moveend", updateData);
55     updateData();
56
57     $("#browse_filter_toggle").toggle(enableFilter, disableFilter);
58
59     $("#browse_hide_areas_box").html(I18n.t('browse.start_rjs.hide_areas'));
60     $("#browse_hide_areas_box").toggle(hideAreas, showAreas);
61
62     function updateData() {
63       if (!locationFilter.isEnabled()) {
64         if (map.getZoom() >= 15) {
65           var bounds = map.getBounds();
66           if (!browseBounds || !browseBounds.contains(bounds)) {
67             browseBounds = bounds;
68             getData();
69           }
70         } else {
71           setStatus(I18n.t('browse.start_rjs.zoom_or_select'));
72         }
73       }
74     }
75
76     $("#sidebar").one("closed", function () {
77       map.removeLayer(dataLayer);
78       map.removeLayer(locationFilter);
79       map.off("moveend", updateData);
80     });
81
82     function enableFilter() {
83       $("#browse_filter_toggle").html(I18n.t('browse.start_rjs.view_data'));
84       locationFilter.enable();
85       getData();
86     }
87
88     function disableFilter() {
89       $("#browse_filter_toggle").html(I18n.t('browse.start_rjs.manually_select'));
90       locationFilter.disable();
91       getData();
92     }
93
94     function hideAreas() {
95       $("#browse_hide_areas_box").html(I18n.t('browse.start_rjs.show_areas'));
96       areasHidden = true;
97       getData();
98     }
99
100     function showAreas() {
101       $("#browse_hide_areas_box").html(I18n.t('browse.start_rjs.hide_areas'));
102       areasHidden = false;
103       getData();
104     }
105
106     function displayFeatureWarning(count, limit, callback) {
107       clearStatus();
108
109       var div = document.createElement("div");
110
111       var p = document.createElement("p");
112       p.appendChild(document.createTextNode(I18n.t("browse.start_rjs.loaded_an_area_with_num_features", { num_features: count, max_features: limit })));
113       div.appendChild(p);
114
115       var input = document.createElement("input");
116       input.type = "submit";
117       input.value = I18n.t('browse.start_rjs.load_data');
118       input.onclick = callback;
119       div.appendChild(input);
120
121       $("#browse_content").html("");
122       $("#browse_content").append(div);
123     }
124
125     function getData() {
126       var bounds = locationFilter.isEnabled() ? locationFilter.getBounds() : map.getBounds();
127       var size = bounds.getSize();
128
129       if (size > OSM.MAX_REQUEST_AREA) {
130         setStatus(I18n.t("browse.start_rjs.unable_to_load_size", { max_bbox_size: OSM.MAX_REQUEST_AREA, bbox_size: size }));
131         return;
132       }
133
134       setStatus(I18n.t('browse.start_rjs.loading'));
135
136       var url = "/api/" + OSM.API_VERSION + "/map?bbox=" + bounds.toBBOX();
137
138       /*
139        * Modern browsers are quite happy showing far more than 100 features in
140        * the data browser, so increase the limit to 2000 by default, but keep
141        * it restricted to 500 for IE8 and 100 for older IEs.
142        */
143       var maxFeatures = 2000;
144
145       /*@cc_on
146         if (navigator.appVersion < 8) {
147           maxFeatures = 100;
148         } else if (navigator.appVersion < 9) {
149           maxFeatures = 500;
150         }
151       @*/
152
153       $.ajax({
154         url: url,
155         success: function (xml) {
156           clearStatus();
157
158           $("#browse_content").empty();
159           dataLayer.clearLayers();
160           selectedLayer = null;
161
162           dataLayer.addData(xml);
163
164           layersById = {};
165           var features = [];
166
167           dataLayer.eachLayer(function (layer) {
168             var feature = layer.feature;
169             layersById[feature.id] = layer;
170             features.push({
171               typeName: featureTypeName(feature),
172               url: "/browse/" + feature.type + "/" + feature.id,
173               name: featureName(feature),
174               id: feature.id
175             });
176           });
177
178           browseObjectList = $(JST["templates/browse/feature_list"]({
179             features: features,
180             url: url
181           }))[0];
182
183           loadObjectList();
184         }
185       });
186     }
187
188     function viewFeatureLink() {
189       var layer = layersById[$(this).data("feature-id")];
190
191       onSelect(layer);
192
193       if (locationFilter.isEnabled()) {
194         map.panTo(layer.getBounds().getCenter());
195       }
196
197       return false;
198     }
199
200     function loadObjectList() {
201       $("#browse_content").html(browseObjectList);
202       $("#browse_content").find("a[data-feature-id]").click(viewFeatureLink);
203
204       return false;
205     }
206
207     function onSelect(layer) {
208       // Unselect previously selected feature
209       if (selectedLayer) {
210         selectedLayer.setStyle(selectedLayer.originalStyle);
211       }
212
213       // Redraw in selected style
214       layer.originalStyle = layer.options;
215       layer.setStyle({color: '#0000ff', weight: 8});
216
217       // If the current object is the list, don't innerHTML="", since that could clear it.
218       if ($("#browse_content").firstChild == browseObjectList) {
219         $("#browse_content").removeChild(browseObjectList);
220       } else {
221         $("#browse_content").empty();
222       }
223
224       var feature = layer.feature;
225
226       $("#browse_content").html(JST["templates/browse/feature"]({
227         name: featureNameSelect(feature),
228         url: "/browse/" + feature.type + "/" + feature.id,
229         attributes: feature.tags
230       }));
231
232       $("#browse_content").find("a.browse_show_list").click(loadObjectList);
233       $("#browse_content").find("a.browse_show_history").click(loadHistory);
234
235       // Stash the currently drawn feature
236       selectedLayer = layer;
237     }
238
239     dataLayer.on("click", function (e) {
240       onSelect(e.layer);
241     });
242
243     function loadHistory() {
244       $(this).attr("href", "").text(I18n.t('browse.start_rjs.wait'));
245
246       var feature = selectedLayer.feature;
247
248       $.ajax({
249         url: "/api/" + OSM.API_VERSION + "/" + feature.type + "/" + feature.id + "/history",
250         success: function (xml) {
251           if (selectedLayer.feature != feature || $("#browse_content").firstChild == browseObjectList) {
252             return;
253           }
254
255           $(this).remove();
256
257           var history = [];
258           var nodes = xml.getElementsByTagName(feature.type);
259           for (var i = nodes.length - 1; i >= 0; i--) {
260             history.push({
261               user: nodes[i].getAttribute("user") || I18n.t('browse.start_rjs.private_user'),
262               timestamp: nodes[i].getAttribute("timestamp")
263             });
264           }
265
266           $("#browse_content").append(JST["templates/browse/feature_history"]({
267             name: featureNameHistory(feature),
268             url: "/browse/" + feature.type + "/" + feature.id,
269             history: history
270           }));
271         }.bind(this)
272       });
273
274       return false;
275     }
276
277     function featureTypeName(feature) {
278       return I18n.t('browse.start_rjs.object_list.type.' + feature.type);
279     }
280
281     function featureName(feature) {
282       return feature.tags['name:' + $('html').attr('lang')] ||
283         feature.tags.name ||
284         feature.id;
285     }
286
287     function featureNameSelect(feature) {
288       return feature.tags['name:' + $('html').attr('lang')] ||
289         feature.tags.name ||
290         I18n.t("browse.start_rjs.object_list.selected.type." + feature.type, { id: feature.id });
291     }
292
293     function featureNameHistory(feature) {
294       return feature.tags['name:' + $('html').attr('lang')] ||
295         feature.tags.name ||
296         I18n.t("browse.start_rjs.object_list.history.type." + feature.type, { id: feature.id });
297     }
298
299     function setStatus(status) {
300       $("#browse_status").html(status);
301       $("#browse_status").show();
302     }
303
304     function clearStatus() {
305       $("#browse_status").html("");
306       $("#browse_status").hide();
307     }
308   }
309 });