]> git.openstreetmap.org Git - rails.git/blob - app/assets/javascripts/leaflet.share.js
d55b0bbd9ffea032d2d38fee65b173c379f406c4
[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     var $shortLink, $longLink;
65
66     $('<ul>')
67       .appendTo($linkSection)
68       .append($('<li>')
69         .append($longLink = $('<a>')
70           .text(I18n.t('javascripts.share.long_link'))))
71       .append($('<li>')
72         .append($shortLink = $('<a>')
73           .text(I18n.t('javascripts.share.short_link'))));
74
75     // Embeddable HTML
76
77     var $embedSection = $('<div>')
78       .attr('class', 'section share-html')
79       .appendTo($ui);
80
81     $('<h4>')
82       .text(I18n.t('javascripts.share.embed'))
83       .appendTo($embedSection);
84
85     $form = $('<form>')
86       .attr('class', 'standard-form')
87       .appendTo($embedSection);
88
89     $('<div>')
90       .attr('class', 'form-row')
91       .appendTo($form)
92       .append(
93         $('<label>')
94           .attr('for', 'embed_marker')
95           .append(
96             $('<input>')
97               .attr('id', 'embed_marker')
98               .attr('type', 'checkbox')
99               .bind('change', toggleMarker))
100           .append(I18n.t('javascripts.share.include_marker')));
101
102     $('<div>')
103       .attr('class', 'form-row')
104       .appendTo($form)
105       .append(
106         $('<textarea>')
107           .attr('id', 'embed_html')
108           .on('click', select));
109
110     $('<p>')
111       .attr('class', 'deemphasize')
112       .text(I18n.t('javascripts.share.paste_html'))
113       .appendTo($embedSection);
114
115     // Image
116
117     var $imageSection = $('<div>')
118       .attr('class', 'section share-image')
119       .appendTo($ui);
120
121     $('<h4>')
122       .text(I18n.t('javascripts.share.image'))
123       .appendTo($imageSection);
124
125     $form = $('<form>')
126       .attr('class', 'standard-form')
127       .attr('action', '/export/finish')
128       .attr('method', 'post')
129       .appendTo($imageSection);
130
131     $('<div>')
132       .attr('class', 'form-row')
133       .appendTo($form)
134       .append(
135         $('<label>')
136           .attr('for', 'image_filter')
137           .append(
138             $('<input>')
139               .attr('id', 'image_filter')
140               .attr('type', 'checkbox')
141               .bind('change', toggleFilter))
142           .append(I18n.t('javascripts.share.custom_dimensions')));
143
144     $('<div>')
145       .attr('class', 'form-row')
146       .appendTo($form)
147       .append(
148         $('<label>')
149           .attr('class', 'standard-label')
150           .attr('for', 'mapnik_format')
151           .text(I18n.t('javascripts.share.format')))
152       .append($('<select>')
153         .attr('name', 'mapnik_format')
154         .attr('id', 'mapnik_format')
155         .append($('<option>').val('png').text('PNG').prop('selected', true))
156         .append($('<option>').val('jpeg').text('JPEG'))
157         .append($('<option>').val('svg').text('SVG'))
158         .append($('<option>').val('pdf').text('PDF')));
159
160     $('<div>')
161       .attr('class', 'form-row')
162       .appendTo($form)
163       .append($('<label>')
164         .attr('class', 'standard-label')
165         .attr('for', 'mapnik_scale')
166         .text(I18n.t('javascripts.share.scale')))
167       .append('1 : ')
168       .append($('<input>')
169         .attr('name', 'mapnik_scale')
170         .attr('id', 'mapnik_scale')
171         .attr('type', 'text')
172         .on('change', update));
173
174     ['minlon', 'minlat', 'maxlon', 'maxlat'].forEach(function(name) {
175       $('<input>')
176         .attr('id', 'mapnik_' + name)
177         .attr('name', name)
178         .attr('type', 'hidden')
179         .appendTo($form);
180     });
181
182     $('<input>')
183       .attr('name', 'format')
184       .attr('value', 'mapnik')
185       .attr('type', 'hidden')
186       .appendTo($form);
187
188     $('<p>')
189       .attr('class', 'deemphasize')
190       .html(I18n.t('javascripts.share.image_size') + ' <span id="mapnik_image_width"></span> x <span id="mapnik_image_height"></span>')
191       .appendTo($form);
192
193     $('<input>')
194       .attr('type', 'submit')
195       .attr('value', I18n.t('javascripts.share.download'))
196       .appendTo($form);
197
198     locationFilter
199       .on('change', update)
200       .addTo(map);
201
202     map.on('moveend layeradd layerremove', update);
203     marker.on('dragend', update);
204
205     options.sidebar.addPane($ui);
206
207     function toggle(e) {
208       e.stopPropagation();
209       e.preventDefault();
210
211       $('#mapnik_scale').val(getScale());
212       marker.setLatLng(map.getCenter());
213
214       update();
215       options.sidebar.togglePane($ui);
216     }
217
218     function toggleMarker() {
219       if ($(this).is(':checked')) {
220         map.addLayer(marker);
221       } else {
222         map.removeLayer(marker);
223       }
224       update();
225     }
226
227     function toggleFilter() {
228       if ($(this).is(':checked')) {
229         if (!locationFilter.getBounds().isValid()) {
230           locationFilter.setBounds(map.getBounds().pad(-0.2));
231         }
232
233         locationFilter.enable();
234       } else {
235         locationFilter.disable();
236       }
237       update();
238     }
239
240     function update() {
241       var bounds = map.getBounds();
242
243       $('#link_marker, #embed_marker')
244         .prop('checked', map.hasLayer(marker));
245
246       // Link
247
248       $shortLink.attr('href', map.getShortUrl(marker));
249       $longLink.attr('href', map.getUrl(marker));
250
251       // Embed
252
253       var params = {
254         bbox: bounds.toBBoxString(),
255         layer: map.getMapBaseLayerId()
256       };
257
258       if (map.hasLayer(marker)) {
259         params.marker = marker.getLatLng().lat + ',' + marker.getLatLng().lng;
260       }
261
262       $('#embed_html').val(
263         '<iframe width="425" height="350" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="' +
264           'http://' + OSM.SERVER_URL + '/export/embed.html?' + $.param(params) +
265           '" style="border: 1px solid black"></iframe><br/>' +
266           '<small><a href="' + map.getUrl(marker) + '</a></small>');
267
268       // Image
269
270       if (locationFilter.isEnabled()) {
271         bounds = locationFilter.getBounds();
272       }
273
274       var scale = $("#mapnik_scale").val(),
275         size = L.bounds(L.CRS.EPSG3857.project(bounds.getSouthWest()),
276                         L.CRS.EPSG3857.project(bounds.getNorthEast())).getSize(),
277         maxScale = Math.floor(Math.sqrt(size.x * size.y / 0.3136));
278
279       $('#mapnik_minlon').val(bounds.getWest());
280       $('#mapnik_minlat').val(bounds.getSouth());
281       $('#mapnik_maxlon').val(bounds.getEast());
282       $('#mapnik_maxlat').val(bounds.getNorth());
283
284       if (scale < maxScale) {
285         scale = roundScale(maxScale);
286         $("#mapnik_scale").val(scale);
287       }
288
289       $("#mapnik_image_width").text(Math.round(size.x / scale / 0.00028));
290       $("#mapnik_image_height").text(Math.round(size.y / scale / 0.00028));
291     }
292
293     function select() {
294       $(this).select();
295     }
296
297     function getScale() {
298       var bounds = map.getBounds(),
299         centerLat = bounds.getCenter().lat,
300         halfWorldMeters = 6378137 * Math.PI * Math.cos(centerLat * Math.PI / 180),
301         meters = halfWorldMeters * (bounds.getEast() - bounds.getWest()) / 180,
302         pixelsPerMeter = map.getSize().x / meters,
303         metersPerPixel = 1 / (92 * 39.3701);
304       return Math.round(1 / (pixelsPerMeter * metersPerPixel));
305     }
306
307     function roundScale(scale) {
308       var precision = 5 * Math.pow(10, Math.floor(Math.LOG10E * Math.log(scale)) - 2);
309       return precision * Math.ceil(scale / precision);
310     }
311
312     return $container[0];
313   };
314
315   return control;
316 };