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