]> git.openstreetmap.org Git - rails.git/blob - app/assets/javascripts/index/browse.js
Restore maxFeatures check
[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           var features = dataLayer.buildFeatures(xml);
163
164           function addFeatures() {
165             dataLayer.addData(features);
166
167             layersById = {};
168
169             dataLayer.eachLayer(function (layer) {
170               var feature = layer.feature;
171               layersById[feature.id] = layer;
172               $.extend(feature, {
173                 typeName: featureTypeName(feature),
174                 url: "/browse/" + feature.type + "/" + feature.id,
175                 name: featureName(feature)
176               });
177             });
178
179             browseObjectList = $(JST["templates/browse/feature_list"]({
180               features: features,
181               url: url
182             }))[0];
183
184             loadObjectList();
185           }
186
187           if (features.length < maxFeatures) {
188             addFeatures();
189           } else {
190             displayFeatureWarning(features.length, maxFeatures, addFeatures);
191           }
192         }
193       });
194     }
195
196     function viewFeatureLink() {
197       var layer = layersById[$(this).data("feature-id")];
198
199       onSelect(layer);
200
201       if (locationFilter.isEnabled()) {
202         map.panTo(layer.getBounds().getCenter());
203       }
204
205       return false;
206     }
207
208     function loadObjectList() {
209       $("#browse_content").html(browseObjectList);
210       $("#browse_content").find("a[data-feature-id]").click(viewFeatureLink);
211
212       return false;
213     }
214
215     function onSelect(layer) {
216       // Unselect previously selected feature
217       if (selectedLayer) {
218         selectedLayer.setStyle(selectedLayer.originalStyle);
219       }
220
221       // Redraw in selected style
222       layer.originalStyle = layer.options;
223       layer.setStyle({color: '#0000ff', weight: 8});
224
225       // If the current object is the list, don't innerHTML="", since that could clear it.
226       if ($("#browse_content").firstChild == browseObjectList) {
227         $("#browse_content").removeChild(browseObjectList);
228       } else {
229         $("#browse_content").empty();
230       }
231
232       var feature = layer.feature;
233
234       $("#browse_content").html(JST["templates/browse/feature"]({
235         name: featureNameSelect(feature),
236         url: "/browse/" + feature.type + "/" + feature.id,
237         attributes: feature.tags
238       }));
239
240       $("#browse_content").find("a.browse_show_list").click(loadObjectList);
241       $("#browse_content").find("a.browse_show_history").click(loadHistory);
242
243       // Stash the currently drawn feature
244       selectedLayer = layer;
245     }
246
247     dataLayer.on("click", function (e) {
248       onSelect(e.layer);
249     });
250
251     function loadHistory() {
252       $(this).attr("href", "").text(I18n.t('browse.start_rjs.wait'));
253
254       var feature = selectedLayer.feature;
255
256       $.ajax({
257         url: "/api/" + OSM.API_VERSION + "/" + feature.type + "/" + feature.id + "/history",
258         success: function (xml) {
259           if (selectedLayer.feature != feature || $("#browse_content").firstChild == browseObjectList) {
260             return;
261           }
262
263           $(this).remove();
264
265           var history = [];
266           var nodes = xml.getElementsByTagName(feature.type);
267           for (var i = nodes.length - 1; i >= 0; i--) {
268             history.push({
269               user: nodes[i].getAttribute("user") || I18n.t('browse.start_rjs.private_user'),
270               timestamp: nodes[i].getAttribute("timestamp")
271             });
272           }
273
274           $("#browse_content").append(JST["templates/browse/feature_history"]({
275             name: featureNameHistory(feature),
276             url: "/browse/" + feature.type + "/" + feature.id,
277             history: history
278           }));
279         }.bind(this)
280       });
281
282       return false;
283     }
284
285     function featureTypeName(feature) {
286       return I18n.t('browse.start_rjs.object_list.type.' + feature.type);
287     }
288
289     function featureName(feature) {
290       return feature.tags['name:' + $('html').attr('lang')] ||
291         feature.tags.name ||
292         feature.id;
293     }
294
295     function featureNameSelect(feature) {
296       return feature.tags['name:' + $('html').attr('lang')] ||
297         feature.tags.name ||
298         I18n.t("browse.start_rjs.object_list.selected.type." + feature.type, { id: feature.id });
299     }
300
301     function featureNameHistory(feature) {
302       return feature.tags['name:' + $('html').attr('lang')] ||
303         feature.tags.name ||
304         I18n.t("browse.start_rjs.object_list.history.type." + feature.type, { id: feature.id });
305     }
306
307     function setStatus(status) {
308       $("#browse_status").html(status);
309       $("#browse_status").show();
310     }
311
312     function clearStatus() {
313       $("#browse_status").html("");
314       $("#browse_status").hide();
315     }
316   }
317 });