]> git.openstreetmap.org Git - rails.git/blob - app/views/export/start.js.erb
Allow OpenStreetMap.js to work with an unpatched OpenLayers
[rails.git] / app / views / export / start.js.erb
1 var vectors;
2 var box;
3 var markerLayer;
4 var markerControl;
5
6 function startExport() {
7   vectors = new OpenLayers.Layer.Vector("Vector Layer", {
8     displayInLayerSwitcher: false
9   });
10   map.addLayer(vectors);
11
12   box = new OpenLayers.Control.DrawFeature(vectors, OpenLayers.Handler.RegularPolygon, {
13     handlerOptions: {
14       sides: 4,
15       snapAngle: 90,
16       irregular: true,
17       persist: true
18     }
19   });
20   box.handler.callbacks.done = endDrag;
21   map.addControl(box);
22
23   map.events.register("moveend", map, mapMoved);
24   map.events.register("changebaselayer", map, htmlUrlChanged);
25
26   $("#sidebar_title").html("<%=j t 'export.start_rjs.export' %>");
27   $("#sidebar_content").html("<%=j render :partial => "sidebar" %>");
28
29   $("#maxlat").change(boundsChanged);
30   $("#minlon").change(boundsChanged);
31   $("#maxlon").change(boundsChanged);
32   $("#minlat").change(boundsChanged);
33
34   $("#drag_box").click(startDrag);
35
36   $("#add_marker").click(startMarker);
37
38   $("#format_osm").click(formatChanged);
39   $("#format_mapnik").click(formatChanged);
40   $("#format_osmarender").click(formatChanged);
41   $("#format_html").click(formatChanged);
42
43   $("#mapnik_scale").change(mapnikSizeChanged);
44
45   openSidebar({ onclose: stopExport });
46
47   if (map.baseLayer.name == "Mapnik") {
48     $("#format_mapnik").prop("checked", true);
49   } else if (map.baseLayer.name == "Osmarender") {
50     $("#format_osmarender").prop("checked", true);
51   }
52
53   formatChanged();
54   setBounds(map.getExtent());
55
56   $("#viewanchor").removeClass("active");
57   $("#exportanchor").addClass("active");
58 }
59
60 function stopExport() {
61   $("#viewanchor").addClass("active");
62   $("#exportanchor").removeClass("active");
63
64   clearBox();
65   clearMarker();
66   map.events.unregister("moveend", map, mapMoved);
67   map.events.unregister("changebaselayer", map, htmlUrlChanged);
68   map.removeLayer(vectors);
69 }
70
71 function boundsChanged() {
72   var epsg4326 = new OpenLayers.Projection("EPSG:4326");
73   var bounds = new OpenLayers.Bounds($("#minlon").val(), $("#minlat").val(),
74                                      $("#maxlon").val(), $("#maxlat").val());
75
76   bounds.transform(epsg4326, map.getProjectionObject());
77
78   map.events.unregister("moveend", map, mapMoved);
79   map.zoomToExtent(bounds);
80
81   clearBox();
82   drawBox(bounds);
83
84   validateControls();
85   mapnikSizeChanged();
86 }
87
88 function startDrag() {
89   $("#drag_box").html("<%=j t 'export.start_rjs.drag_a_box' %>");
90
91   clearBox();
92   box.activate();
93 };
94
95 function endDrag(bbox) {
96   var bounds = bbox.getBounds();
97
98   map.events.unregister("moveend", map, mapMoved);
99   setBounds(bounds);
100   drawBox(bounds);
101   box.deactivate();
102   validateControls();
103
104   $("#drag_box").html("<%=j t 'export.start_rjs.manually_select' %>");
105 }
106
107 function startMarker() {
108   $("#add_marker").html("<%=j t 'export.start_rjs.click_add_marker' %>");
109
110   if (!markerLayer) {
111     markerLayer = new OpenLayers.Layer.Vector("",{
112       displayInLayerSwitcher: false,
113       style: {
114         externalGraphic: OpenLayers.Util.getImagesLocation() + "marker.png",
115         graphicXOffset: -10.5,
116         graphicYOffset: -25,
117         graphicWidth: 21,
118         graphicHeight: 25
119       }
120     });
121     map.addLayer(markerLayer);
122
123     markerControl = new OpenLayers.Control.DrawFeature(markerLayer, OpenLayers.Handler.Point);
124     map.addControl(markerControl);
125
126     markerLayer.events.on({ "featureadded": endMarker });
127   }
128
129   markerLayer.destroyFeatures();
130   markerControl.activate();
131
132   return false;
133 }
134
135 function endMarker(event) {
136   markerControl.deactivate();
137
138   $("#add_marker").html("<%=j t 'export.start_rjs.change_marker' %>");
139   $("#marker_inputs").show();
140
141   var epsg4326 = new OpenLayers.Projection("EPSG:4326");
142   var epsg900913 = new OpenLayers.Projection("EPSG:900913");
143   var geom = event.feature.geometry.clone().transform(epsg900913, epsg4326);
144
145   $("#marker_lon").val(geom.x.toFixed(5));
146   $("#marker_lat").val(geom.y.toFixed(5));
147
148   htmlUrlChanged();
149 }
150
151 function clearMarker() {
152   $("#marker_lon").val("");
153   $("#marker_lat").val("");
154   $("#marker_inputs").hide();
155   $("#add_marker").html("<%=j t 'export.start_rjs.add_marker' %>");
156
157   if (markerLayer) {
158     markerControl.destroy();
159     markerLayer.destroy();
160     markerLayer = null;
161     markerControl = null;
162   }
163 }
164
165 function mapMoved() {
166   setBounds(map.getExtent());
167   validateControls();
168 }
169
170 function setBounds(bounds) {
171   var epsg4326 = new OpenLayers.Projection("EPSG:4326");
172   var decimals = Math.pow(10, Math.floor(map.getZoom() / 3));
173
174   bounds = bounds.clone().transform(map.getProjectionObject(), epsg4326);
175
176   $("#minlon").val(Math.round(bounds.left * decimals) / decimals);
177   $("#minlat").val(Math.round(bounds.bottom * decimals) / decimals);
178   $("#maxlon").val(Math.round(bounds.right * decimals) / decimals);
179   $("#maxlat").val(Math.round(bounds.top * decimals) / decimals);
180
181   mapnikSizeChanged();
182   htmlUrlChanged();
183 }
184
185 function clearBox() {
186   vectors.destroyFeatures();
187 }
188
189 function drawBox(bounds) {
190   var feature = new OpenLayers.Feature.Vector(bounds.toGeometry());
191
192   vectors.addFeatures(feature);
193 }
194
195 function validateControls() {
196   var bounds = new OpenLayers.Bounds($("#minlon").val(), $("#minlat").val(), $("#maxlon").val(), $("#maxlat").val());
197
198   if (bounds.getWidth() * bounds.getHeight() > <%= MAX_REQUEST_AREA %>) {
199     $("#export_osm_too_large").show();
200   } else {
201     $("#export_osm_too_large").hide();
202   }
203
204   var max_scale = maxMapnikScale();
205
206   if ($("#format_osm").prop("checked") && bounds.getWidth() * bounds.getHeight() > <%= MAX_REQUEST_AREA %>) {
207     $("#export_commit").prop("disabled", true);
208   } else if ($("#format_mapnik").prop("checked") && $("#mapnik_scale").val() < max_scale) {
209     $("#export_commit").prop("disabled", true);
210   } else {
211     $("#export_commit").prop("disabled", false);
212   }
213
214   $("#mapnik_max_scale").html(roundScale(max_scale));
215
216   var max_zoom = maxOsmarenderZoom();
217
218   $("#osmarender_zoom option").each(function () {
219     if ($(this).val() > max_zoom) {
220       $(this).prop("disabled", true);
221     } else {
222       $(this).prop("disabled", false);
223     }
224   });
225
226   if ($("#osmarender_zoom option").is(":disabled:selected")) {
227     $("#osmarender_zoom option").filter(":enabled").last().prop("selected", true);
228   }
229 }
230
231 function htmlUrlChanged() {
232   var bounds = new OpenLayers.Bounds($("#minlon").val(), $("#minlat").val(), $("#maxlon").val(), $("#maxlat").val());
233   var layerName = map.baseLayer.keyid;
234   var url = "http://<%= SERVER_URL %>/export/embed.html?bbox=" + bounds.toBBOX() + "&amp;layer=" + layerName;
235   var markerUrl = "";
236
237   if ($("#marker_lat").val() && $("#marker_lon").val()) {
238     markerUrl = "&amp;mlat=" + $("#marker_lat").val() + "&amp;mlon=" + $("#marker_lon").val();
239     url += "&amp;marker=" + $("#marker_lat").val() + "," + $("#marker_lon").val();
240   }
241
242   var html = '<iframe width="425" height="350" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="'+url+'" style="border: 1px solid black"></iframe>';
243
244   // Create "larger map" link
245   var center = bounds.getCenterLonLat();
246   var epsg4326 = new OpenLayers.Projection("EPSG:4326");
247   var epsg900913 = new OpenLayers.Projection("EPSG:900913");
248
249   bounds.transform(epsg4326, epsg900913);
250   var zoom = map.getZoomForExtent(bounds);
251
252   var layers = getMapLayers();
253
254   html += '<br /><small><a href="http://<%= SERVER_URL %>/?lat='+center.lat+'&amp;lon='+center.lon+'&amp;zoom='+zoom+'&amp;layers='+layers+markerUrl+'">'+"<%= html_escape_unicode(I18n.t('export.start_rjs.view_larger_map')) %>"+'</a></small>';
255
256   $("#export_html_text").val(html);
257
258   if ($("#format_html").prop("checked")) {
259     $("#export_html_text").prop("selected", true);
260   }
261 }
262
263 function formatChanged() {
264   $("#export_commit").show();
265
266   if ($("#format_osm").prop("checked")) {
267     $("#export_osm").show();
268   } else {
269     $("#export_osm").hide();
270   }
271
272   if ($("#format_mapnik").prop("checked")) {
273     $("#mapnik_scale").val(roundScale(map.getScale()));
274     $("#export_mapnik").show();
275   } else {
276     $("#export_mapnik").hide();
277   }
278
279   if ($("#format_osmarender").prop("checked")) {
280     var zoom = Math.min(map.getZoom(), maxOsmarenderZoom());
281
282     $("#osmarender_zoom option[value=" + zoom + "]").prop("selected", true);
283     $("#export_osmarender").show();
284   } else {
285     $("#export_osmarender").hide();
286   }
287
288   if ($("#format_html").prop("checked")) {
289     $("#export_html").show();
290     $("#export_commit").hide();
291     $("#export_html_text").prop("selected", true);
292   } else {
293     $("#export_html").hide();
294
295     clearMarker();
296   }
297
298   validateControls();
299 }
300
301 function maxMapnikScale() {
302   var bounds = new OpenLayers.Bounds($("#minlon").val(), $("#minlat").val(), $("#maxlon").val(), $("#maxlat").val());
303   var epsg4326 = new OpenLayers.Projection("EPSG:4326");
304   var epsg900913 = new OpenLayers.Projection("EPSG:900913");
305
306   bounds.transform(epsg4326, epsg900913);
307
308   return Math.floor(Math.sqrt(bounds.getWidth() * bounds.getHeight() / 0.3136));
309 }
310
311 function mapnikImageSize(scale) {
312   var bounds = new OpenLayers.Bounds($("#minlon").val(), $("#minlat").val(), $("#maxlon").val(), $("#maxlat").val());
313   var epsg4326 = new OpenLayers.Projection("EPSG:4326");
314   var epsg900913 = new OpenLayers.Projection("EPSG:900913");
315
316   bounds.transform(epsg4326, epsg900913);
317
318   return new OpenLayers.Size(Math.round(bounds.getWidth() / scale / 0.00028),
319                              Math.round(bounds.getHeight() / scale / 0.00028));
320 }
321
322 function maxOsmarenderZoom() {
323   var bounds = new OpenLayers.Bounds($("#minlon").val(), $("#minlat").val(), $("#maxlon").val(), $("#maxlat").val());
324   var xzoom = Math.LOG2E * Math.log(2000 * 1.40625 / bounds.getWidth());
325   var ymin = bounds.bottom * Math.PI / 180;
326   var ymax = bounds.top * Math.PI / 180;
327   var yzoom = Math.LOG2E * (Math.log(2000 * 2 * Math.PI) - Math.log(Math.log((Math.tan(ymax) + 1 / Math.cos(ymax)) / (Math.tan(ymin) + 1 / Math.cos(ymin)))))
328
329   return Math.min(Math.floor(Math.min(xzoom, yzoom)), 17);
330 }
331
332 function roundScale(scale) {
333   var precision = 5 * Math.pow(10, Math.floor(Math.LOG10E * Math.log(scale)) - 2);
334
335   return precision * Math.ceil(scale / precision);
336 }
337
338 function mapnikSizeChanged() {
339   var size = mapnikImageSize($("#mapnik_scale").val());
340
341   $("#mapnik_image_width").html(size.w);
342   $("#mapnik_image_height").html(size.h);
343
344   validateControls();
345 }
346
347 startExport();