]> git.openstreetmap.org Git - rails.git/blob - app/assets/javascripts/leaflet.share.js
4454f02bbddd917b7bff598f600ad793398e818d
[rails.git] / app / assets / javascripts / leaflet.share.js
1 L.OSM.share = function (options) {
2   var control = L.control(options),
3     marker = L.marker([0, 0], {draggable: true}),
4     locationFilter = new L.LocationFilter({
5       enableButton: false,
6       adjustButton: false
7     });
8
9   control.onAdd = function (map) {
10     var $container = $('<div>')
11       .attr('class', 'control-share');
12
13     $('<a>')
14       .attr('class', 'control-button')
15       .attr('href', '#')
16       .attr('title', 'Share')
17       .html('<span class="icon share"></span>')
18       .on('click', toggle)
19       .appendTo($container);
20
21     var $ui = $('<div>')
22       .attr('class', 'share-ui');
23
24     $('<div>')
25       .attr('class', 'sidebar_heading')
26       .appendTo($ui)
27       .append(
28         $('<a>')
29           .text(I18n.t('javascripts.close'))
30           .attr('class', 'sidebar_close')
31           .attr('href', '#')
32           .bind('click', toggle))
33       .append(
34         $('<h4>')
35           .text(I18n.t('javascripts.share.title')));
36
37     // Link
38
39     var $linkSection = $('<div>')
40       .attr('class', 'section share-link')
41       .appendTo($ui);
42
43     $('<h4>')
44       .text(I18n.t('javascripts.share.link'))
45       .appendTo($linkSection);
46
47     var $form = $('<form>')
48       .attr('class', 'standard-form')
49       .appendTo($linkSection);
50
51     $('<div>')
52       .attr('class', 'form-row')
53       .appendTo($form)
54       .append(
55         $('<label>')
56           .attr('for', 'link_marker')
57           .append(
58             $('<input>')
59               .attr('id', 'link_marker')
60               .attr('type', 'checkbox')
61               .bind('change', toggleMarker))
62           .append(I18n.t('javascripts.share.include_marker')));
63
64     $('<div>')
65       .attr('class', 'form-row')
66       .appendTo($form)
67       .append(
68         $('<label>')
69           .attr('for', 'center_marker')
70           .append(
71             $('<input>')
72               .attr('id', 'center_marker')
73               .attr('type', 'checkbox')
74               .prop('checked', true)
75               .bind('change', update))
76           .append(I18n.t('javascripts.share.center_marker')));
77
78     $('<div>')
79       .attr('class', 'form-row')
80       .appendTo($form)
81       .append($('<label>')
82         .attr('for', 'long_input')
83         .text(I18n.t('javascripts.share.long_link')))
84       .append($('<a>')
85         .attr('id', 'long_link')
86         .append($('<span>')
87           .attr('class', 'icon link')))
88       .append($('<input>')
89         .attr('id', 'long_input')
90         .attr('type', 'text')
91         .on('click', select));
92
93     $('<div>')
94       .attr('class', 'form-row')
95       .appendTo($form)
96       .append($('<label>')
97         .attr('for', 'short_input')
98         .text(I18n.t('javascripts.share.short_link')))
99       .append($('<a>')
100         .attr('id', 'short_link')
101         .append($('<span>')
102           .attr('class', 'icon link')))
103       .append($('<input>')
104         .attr('id', 'short_input')
105         .attr('type', 'text')
106         .on('click', select));
107
108     // Embed
109
110     var $embedSection = $('<div>')
111       .attr('class', 'section share-embed')
112       .appendTo($ui);
113
114     var $form = $('<form>')
115       .attr('class', 'standard-form')
116       .appendTo($embedSection);
117
118     $('<div>')
119       .attr('class', 'form-row')
120       .appendTo($form)
121       .append($('<label>')
122         .attr('for', 'embed_html')
123         .text(I18n.t('javascripts.share.embed')))
124       .append(
125         $('<textarea>')
126           .attr('id', 'embed_html')
127           .on('click', select));
128
129     $('<p>')
130       .attr('class', 'deemphasize')
131       .text(I18n.t('javascripts.share.paste_html'))
132       .appendTo($linkSection);
133
134     // Image
135
136     var $imageSection = $('<div>')
137       .attr('class', 'section share-image')
138       .appendTo($ui);
139
140     $('<h4>')
141       .text(I18n.t('javascripts.share.image'))
142       .appendTo($imageSection);
143
144     $form = $('<form>')
145       .attr('class', 'standard-form')
146       .attr('action', '/export/finish')
147       .attr('method', 'post')
148       .appendTo($imageSection);
149
150     $('<div>')
151       .attr('class', 'form-row')
152       .appendTo($form)
153       .append(
154         $('<label>')
155           .attr('for', 'image_filter')
156           .append(
157             $('<input>')
158               .attr('id', 'image_filter')
159               .attr('type', 'checkbox')
160               .bind('change', toggleFilter))
161           .append(I18n.t('javascripts.share.custom_dimensions')));
162
163     $('<div>')
164       .attr('class', 'form-row')
165       .appendTo($form)
166       .append(
167         $('<label>')
168           .attr('class', 'standard-label')
169           .attr('for', 'mapnik_format')
170           .text(I18n.t('javascripts.share.format')))
171       .append($('<select>')
172         .attr('name', 'mapnik_format')
173         .attr('id', 'mapnik_format')
174         .append($('<option>').val('png').text('PNG').prop('selected', true))
175         .append($('<option>').val('jpeg').text('JPEG'))
176         .append($('<option>').val('svg').text('SVG'))
177         .append($('<option>').val('pdf').text('PDF')));
178
179     $('<div>')
180       .attr('class', 'form-row')
181       .appendTo($form)
182       .append($('<label>')
183         .attr('class', 'standard-label')
184         .attr('for', 'mapnik_scale')
185         .text(I18n.t('javascripts.share.scale')))
186       .append('1 : ')
187       .append($('<input>')
188         .attr('name', 'mapnik_scale')
189         .attr('id', 'mapnik_scale')
190         .attr('type', 'text')
191         .on('change', update));
192
193     ['minlon', 'minlat', 'maxlon', 'maxlat'].forEach(function(name) {
194       $('<input>')
195         .attr('id', 'mapnik_' + name)
196         .attr('name', name)
197         .attr('type', 'hidden')
198         .appendTo($form);
199     });
200
201     $('<input>')
202       .attr('name', 'format')
203       .attr('value', 'mapnik')
204       .attr('type', 'hidden')
205       .appendTo($form);
206
207     $('<p>')
208       .attr('class', 'deemphasize')
209       .html(I18n.t('javascripts.share.image_size') + ' <span id="mapnik_image_width"></span> x <span id="mapnik_image_height"></span>')
210       .appendTo($form);
211
212     $('<input>')
213       .attr('type', 'submit')
214       .attr('value', I18n.t('javascripts.share.download'))
215       .appendTo($form);
216
217     locationFilter
218       .on('change', update)
219       .addTo(map);
220
221     map.on('moveend layeradd layerremove', update);
222     marker.on('dragend', update);
223
224     options.sidebar.addPane($ui);
225
226     $ui
227       .on('hide', hidden);
228
229     function hidden() {
230       map.removeLayer(marker);
231       locationFilter.disable();
232       update();
233     }
234
235     function toggle(e) {
236       e.stopPropagation();
237       e.preventDefault();
238
239       $('#mapnik_scale').val(getScale());
240       marker.setLatLng(map.getCenter());
241
242       update();
243       options.sidebar.togglePane($ui);
244     }
245
246     function toggleMarker() {
247       if ($(this).is(':checked')) {
248         marker.setLatLng(map.getCenter());
249         map.addLayer(marker);
250       } else {
251         map.removeLayer(marker);
252       }
253       update();
254     }
255
256     function toggleFilter() {
257       if ($(this).is(':checked')) {
258         if (!locationFilter.getBounds().isValid()) {
259           locationFilter.setBounds(map.getBounds().pad(-0.2));
260         }
261
262         locationFilter.enable();
263       } else {
264         locationFilter.disable();
265       }
266       update();
267     }
268
269     function update() {
270       if (map.hasLayer(marker) && $('#center_marker').is(':checked')) {
271         map.panTo(marker.getLatLng());
272       }
273
274       var bounds = map.getBounds();
275
276       $('#link_marker')
277         .prop('checked', map.hasLayer(marker));
278
279       $('#center_marker')
280         .prop('disabled', !map.hasLayer(marker));
281
282       $('#image_filter')
283         .prop('checked', locationFilter.isEnabled());
284
285       // Link / Embed
286
287       $('#short_input').val(map.getShortUrl(marker));
288       $('#long_input').val(map.getUrl(marker));
289       $('#short_link').attr('href', map.getShortUrl(marker));
290       $('#long_link').attr('href', map.getUrl(marker));
291
292       var params = {
293         bbox: bounds.toBBoxString(),
294         layer: map.getMapBaseLayerId()
295       };
296
297       if (map.hasLayer(marker)) {
298         params.marker = marker.getLatLng().lat + ',' + marker.getLatLng().lng;
299       }
300
301       $('#embed_html').val(
302         '<iframe width="425" height="350" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="' +
303           escapeHTML('http://' + OSM.SERVER_URL + '/export/embed.html?' + $.param(params)) +
304           '" style="border: 1px solid black"></iframe><br/>' +
305           '<small><a href="' + escapeHTML(map.getUrl(marker)) + '</a></small>');
306
307       // Image
308
309       if (locationFilter.isEnabled()) {
310         bounds = locationFilter.getBounds();
311       }
312
313       var scale = $("#mapnik_scale").val(),
314         size = L.bounds(L.CRS.EPSG3857.project(bounds.getSouthWest()),
315                         L.CRS.EPSG3857.project(bounds.getNorthEast())).getSize(),
316         maxScale = Math.floor(Math.sqrt(size.x * size.y / 0.3136));
317
318       $('#mapnik_minlon').val(bounds.getWest());
319       $('#mapnik_minlat').val(bounds.getSouth());
320       $('#mapnik_maxlon').val(bounds.getEast());
321       $('#mapnik_maxlat').val(bounds.getNorth());
322
323       if (scale < maxScale) {
324         scale = roundScale(maxScale);
325         $("#mapnik_scale").val(scale);
326       }
327
328       $("#mapnik_image_width").text(Math.round(size.x / scale / 0.00028));
329       $("#mapnik_image_height").text(Math.round(size.y / scale / 0.00028));
330     }
331
332     function select() {
333       $(this).select();
334     }
335
336     function getScale() {
337       var bounds = map.getBounds(),
338         centerLat = bounds.getCenter().lat,
339         halfWorldMeters = 6378137 * Math.PI * Math.cos(centerLat * Math.PI / 180),
340         meters = halfWorldMeters * (bounds.getEast() - bounds.getWest()) / 180,
341         pixelsPerMeter = map.getSize().x / meters,
342         metersPerPixel = 1 / (92 * 39.3701);
343       return Math.round(1 / (pixelsPerMeter * metersPerPixel));
344     }
345
346     function roundScale(scale) {
347       var precision = 5 * Math.pow(10, Math.floor(Math.LOG10E * Math.log(scale)) - 2);
348       return precision * Math.ceil(scale / precision);
349     }
350
351     return $container[0];
352   };
353
354   return control;
355 };