//= require_self //= require_tree ./directions_engines OSM.Directions = function (map) { var awaitingGeocode; // true if the user has requested a route, but we're waiting on a geocode result var awaitingRoute; // true if we've asked the engine for a route and are waiting to hear back var dragging; // true if the user is dragging a start/end point var chosenEngine; var popup = L.popup(); var polyline = L.polyline([], { color: '#03f', opacity: 0.3, weight: 10 }); var highlight = L.polyline([], { color: '#ff0', opacity: 0.5, weight: 12 }); var endpoints = [ Endpoint($("input[name='route_from']"), <%= asset_path('marker-green.png').to_json %>), Endpoint($("input[name='route_to']"), <%= asset_path('marker-red.png').to_json %>) ]; function Endpoint(input, iconUrl) { var endpoint = {}; endpoint.marker = L.marker([0, 0], { icon: L.icon({ iconUrl: iconUrl, iconSize: [25, 41], iconAnchor: [12, 41], popupAnchor: [1, -34], shadowUrl: <%= asset_path('images/marker-shadow.png').to_json %>, shadowSize: [41, 41] }), draggable: true }); endpoint.marker.on('drag dragend', function (e) { dragging = (e.type == 'drag'); if (dragging && !chosenEngine.draggable) return; if (dragging && awaitingRoute) return; endpoint.setLatLng(e.target.getLatLng()); r.requestRoute(!dragging, false); }); input.on("change", function (e) { endpoint.awaitingGeocode = true; $.getJSON('<%= NOMINATIM_URL %>search?q=' + encodeURIComponent(e.target.value) + '&format=json', function (json) { endpoint.awaitingGeocode = false; if (json.length == 0) { alert(I18n.t('javascripts.directions.errors.no_place')); return; } input.val(json[0].display_name); endpoint.latlng = L.latLng(json[0]); endpoint.marker .setLatLng(endpoint.latlng) .addTo(map); if (awaitingGeocode) { awaitingGeocode = false; r.requestRoute(true, true); } }); }); endpoint.setLatLng = function (ll) { input.val(Math.round(ll.lat * 10000) / 10000 + " " + Math.round(ll.lng * 10000) / 10000); endpoint.latlng = ll; endpoint.marker .setLatLng(ll) .addTo(map); }; return endpoint; } function formatDistance(m) { if (m < 1000) { return Math.round(m) + "m"; } else if (m < 10000) { return (m / 1000.0).toFixed(1) + "km"; } else { return Math.round(m / 1000) + "km"; } } function formatTime(s) { var m = Math.round(s / 60); var h = Math.floor(m / 60); m -= h * 60; return h + ":" + (m < 10 ? '0' : '') + m; } var engines = OSM.Directions.engines; engines.sort(function (a, b) { return I18n.t(a.name) > I18n.t(b.name); }); var select = $('select.routing_engines'); for (var i = 0; i < engines.length; i++) { var engine = engines[i]; select.append(""); if (engine.name == 'javascripts.directions.engines.osrm_car') { chosenEngine = engine; select.val(i); } } select.on("change", function (e) { chosenEngine = engines[e.target.selectedIndex]; if (map.hasLayer(polyline)) { // and if a route is currently showing, must also refresh, else confusion r.requestRoute(true, false); } }); $(".get_directions").on("click", function (e) { e.preventDefault(); $(".search").hide(); $(".routing").show(); $(".search_form input[type='submit']").addClass("routing_submit"); $(".query_wrapper.routing [name=route_from]").focus(); $("#map").on('dragend dragover', function (e) { e.preventDefault(); }); $("#map").on('drop', function (e) { e.preventDefault(); var oe = e.originalEvent; var id = oe.dataTransfer.getData('id'); var pt = L.DomEvent.getMousePosition(oe, map.getContainer()); // co-ordinates of the mouse pointer at present pt.x += Number(oe.dataTransfer.getData('offsetX')); pt.y += Number(oe.dataTransfer.getData('offsetY')); var ll = map.containerPointToLatLng(pt); endpoints[id === 'marker_from' ? 0 : 1].setLatLng(ll); r.requestRoute(true, false); }); $(".routing_marker").on('dragstart', function (e) { e.originalEvent.dataTransfer.effectAllowed = 'move'; e.originalEvent.dataTransfer.setData('id', this.id); var xo = e.originalEvent.clientX - $(e.target).offset().left; var yo = e.originalEvent.clientY - $(e.target).offset().top; e.originalEvent.dataTransfer.setData('offsetX', e.originalEvent.target.width / 2 - xo); e.originalEvent.dataTransfer.setData('offsetY', e.originalEvent.target.height - yo); }); }); $(".close_directions").on("click", function (e) { e.preventDefault(); $(".search").show(); $(".routing").hide(); $(".search_form input[type='submit']").removeClass("routing_submit"); $("#content").addClass("overlay-sidebar"); $(".query_wrapper.routing input").val(""); map .removeLayer(popup) .removeLayer(polyline) .removeLayer(endpoints[0].marker) .removeLayer(endpoints[1].marker); endpoints[0].latlng = endpoints[1].latlng = null; $("#map").off('dragend drop dragover'); $(".routing_marker").off('dragstart'); $(".query_wrapper.search [name=query]").focus(); }); var r = {}; r.requestRoute = function (isFinal, updateZoom) { if (endpoints[0].awaitingGeocode || endpoints[1].awaitingGeocode) { awaitingGeocode = true; return; } var origin = endpoints[0].latlng, destination = endpoints[1].latlng; if (!origin || !destination) { return; } $(".query_wrapper.routing .spinner").show(); awaitingRoute = true; if (updateZoom) { map.fitBounds(L.latLngBounds(origin, destination).pad(0.05)); } chosenEngine.getRoute(isFinal, [origin, destination], function (err, route) { awaitingRoute = false; $(".query_wrapper.routing .spinner").hide(); if (err) { map.removeLayer(polyline); if (!dragging) { alert(I18n.t('javascripts.directions.errors.no_route')); } return; } polyline .setLatLngs(route.line) .addTo(map); $("#content").removeClass("overlay-sidebar"); var html = ('

' + '' + I18n.t('javascripts.directions.directions') + '

' + I18n.t('javascripts.directions.distance') + ': ' + formatDistance(route.distance) + '. ' + I18n.t('javascripts.directions.time') + ': ' + formatTime(route.time) + '.

' + '').replace(/~/g, "'"); $('#sidebar_content') .html(html); // Add each row var cumulative = 0; route.steps.forEach(function (step) { var ll = step[0], direction = step[1], instruction = step[2], dist = step[3], lineseg = step[4]; cumulative += dist; if (dist < 5) { dist = ""; } else if (dist < 200) { dist = Math.round(dist / 10) * 10 + "m"; } else if (dist < 1500) { dist = Math.round(dist / 100) * 100 + "m"; } else if (dist < 5000) { dist = Math.round(dist / 100) / 10 + "km"; } else { dist = Math.round(dist / 1000) + "km"; } var row = $(""); row.append("
"); row.append("" + instruction); row.append("" + dist); row.on('click', function () { popup .setLatLng(ll) .setContent("

" + instruction + "

") .openOn(map); }); row.hover(function () { highlight .setLatLngs(lineseg) .addTo(map); }, function () { map.removeLayer(highlight); }); $('#turnbyturn').append(row); }); $('#sidebar_content').append('

' + I18n.t('javascripts.directions.instructions.courtesy', {link: chosenEngine.creditline}) + '

'); }); }; return r; }; OSM.Directions.engines = []; OSM.Directions.addEngine = function (engine, supportsHTTPS) { if (document.location.protocol == "http:" || supportsHTTPS) { OSM.Directions.engines.push(engine); } };