diff --git a/WebContent/base/OSRM.Map.js b/WebContent/base/OSRM.Map.js index 7e3df6823..0108a200e 100644 --- a/WebContent/base/OSRM.Map.js +++ b/WebContent/base/OSRM.Map.js @@ -81,7 +81,7 @@ zoomed: function(e) { if(OSRM.G.dragging) OSRM.Routing.getRoute_Dragging(); else - OSRM.Routing.getRoute_Redraw(); + OSRM.Routing.getRoute_Redraw({keepAlternative:true}); }, contextmenu: function(e) {;}, mousemove: function(e) { OSRM.Via.drawDragMarker(e); }, diff --git a/WebContent/base/OSRM.Routes.js b/WebContent/base/OSRM.Routes.js index e03d8fe75..527d0e304 100644 --- a/WebContent/base/OSRM.Routes.js +++ b/WebContent/base/OSRM.Routes.js @@ -20,9 +20,10 @@ or see http://www.gnu.org/licenses/agpl.txt. OSRM.Route = function() { - this._current_route = new OSRM.SimpleRoute("current" , {dashed:false} ); - this._old_route = new OSRM.SimpleRoute("old", {dashed:false,color:"#123"} ); - this._unnamed_route = new OSRM.MultiRoute("unnamed"); + this._current_route = new OSRM.SimpleRoute("current" , {dashed:false} ); + this._alternative_route = new OSRM.SimpleRoute("alternative" , {dashed:false} ); + this._old_route = new OSRM.SimpleRoute("old", {dashed:false,color:"#123"} ); + this._unnamed_route = new OSRM.MultiRoute("unnamed"); this._current_route_style = {dashed:false,color:'#0033FF', weight:5}; this._current_noroute_style = {dashed:true, color:'#222222', weight:2}; @@ -30,6 +31,7 @@ OSRM.Route = function() { this._old_noroute_style = {dashed:true, color:'#000000', weight:2}; this._unnamed_route_style = {dashed:false, color:'#FF00FF', weight:10}; this._old_unnamed_route_style = {dashed:false, color:'#990099', weight:10}; + this._alternative_route_style = {dashed:false,color:'#770033', weight:5, opacity:0.6}; this._noroute = OSRM.Route.ROUTE; this._history = new OSRM.HistoryRoute(); @@ -99,6 +101,16 @@ OSRM.extend( OSRM.Route,{ this._old_route.hide(); }, + // show/hide alternative route + showAlternativeRoute: function(positions) { + this._alternative_route.setPositions( positions ); + this._alternative_route.setStyle( this._alternative_route_style ); + this._alternative_route.show(); + }, + hideAlternativeRoute: function() { + this._alternative_route.hide(); + }, + // query routines isShown: function() { return this._current_route.isShown(); diff --git a/WebContent/gui/OSRM.MainGUI.js b/WebContent/gui/OSRM.MainGUI.js index ae4db5f7f..8fc8a512c 100644 --- a/WebContent/gui/OSRM.MainGUI.js +++ b/WebContent/gui/OSRM.MainGUI.js @@ -101,7 +101,7 @@ afterMainTransition: function() { // toggle distance units onUnitsChanged: function(value) { OSRM.Utils.setToHumanDistanceFunction(value); - OSRM.Routing.getRoute(); + OSRM.Routing.getRoute({keepAlternative:true}); }, // set timestamp of data diff --git a/WebContent/gui/OSRM.RoutingGUI.js b/WebContent/gui/OSRM.RoutingGUI.js index 6b7dfe45f..736d8a86d 100644 --- a/WebContent/gui/OSRM.RoutingGUI.js +++ b/WebContent/gui/OSRM.RoutingGUI.js @@ -40,7 +40,7 @@ init: function() { document.getElementById("gui-reverse").onclick = OSRM.GUI.reverseRouting; document.getElementById("open-josm").onclick = OSRM.GUI.openJOSM; document.getElementById("open-osmbugs").onclick = OSRM.GUI.openOSMBugs; - document.getElementById("option-highlight-nonames").onclick = OSRM.Routing.getRoute_Redraw; + document.getElementById("option-highlight-nonames").onclick = OSRM.GUI.hightlightNonames; document.getElementById("option-show-previous-routes").onclick = OSRM.GUI.showPreviousRoutes; }, @@ -164,6 +164,11 @@ zoomOnRoute: function() { var bounds = new L.LatLngBounds( OSRM.G.route._current_route.getPositions() ); OSRM.G.map.fitBoundsUI(bounds); +}, + +//click: toggle highlighting unnamed streets +hightlightNonames: function() { + OSRM.Routing.getRoute_Redraw({keepAlternative:true}); } }); diff --git a/WebContent/localization/OSRM.Localization.js b/WebContent/localization/OSRM.Localization.js index 25bc56901..952918454 100644 --- a/WebContent/localization/OSRM.Localization.js +++ b/WebContent/localization/OSRM.Localization.js @@ -64,7 +64,7 @@ setLanguage: function(language) { if( OSRM.G.markers == null ) return; if( OSRM.G.markers.route.length > 1) - OSRM.Routing.getRoute(); + OSRM.Routing.getRoute({keepAlternative:true}); else if(OSRM.G.markers.route.length > 0 && document.getElementById('information-box').innerHTML != "" ) { OSRM.Geocoder.call( OSRM.C.SOURCE_LABEL, document.getElementById("gui-input-source").value ); OSRM.Geocoder.call( OSRM.C.TARGET_LABEL, document.getElementById("gui-input-target").value ); diff --git a/WebContent/main.css b/WebContent/main.css index 25deae410..7d2f64fad 100644 --- a/WebContent/main.css +++ b/WebContent/main.css @@ -536,6 +536,21 @@ html, body { outline-style:none; vertical-align:1px; } +.button-pressed +{ + cursor:pointer; + padding:2px 10px 2px 10px; + border-radius:5px; + -moz-border-radius:5px; + -webkit-border-radius:5px; + background-color:#AAAAAA; + border:1px solid #999999; + color:#000000; + text-decoration:none; + font-size:9px; + outline-style:none; + vertical-align:1px; +} /* iconic buttons */ diff --git a/WebContent/main.html b/WebContent/main.html index 18b4e5dd5..f2446407f 100644 --- a/WebContent/main.html +++ b/WebContent/main.html @@ -65,6 +65,7 @@ or see http://www.gnu.org/licenses/agpl.txt. + diff --git a/WebContent/main.js b/WebContent/main.js index 2dd7465ba..008f73cc1 100644 --- a/WebContent/main.js +++ b/WebContent/main.js @@ -29,6 +29,7 @@ OSRM.init = function() { OSRM.Map.init(); OSRM.Printing.init(); OSRM.Routing.init(); + OSRM.RoutingAlternatives.init(); OSRM.Localization.init(); // stop if in maintenance mode @@ -216,7 +217,13 @@ OSRM.parseParameters = function(){ if(coordinates.length!=2 || !OSRM.Utils.isLatitude(coordinates[0]) || !OSRM.Utils.isLongitude(coordinates[1]) ) return; params.center = new L.LatLng( coordinates[0], coordinates[1]); - } + } + else if(name_val[0] == 'alt') { + var active_alternative = Number(name_val[1]); + if( active_alternative<0 || active_alternative>OSRM.RoutingAlternatives>10) // using 10 as arbitrary upper limit + return; + params.active_alternative = active_alternative; + } } // case 1: destination given @@ -255,9 +262,12 @@ OSRM.parseParameters = function(){ } else { OSRM.G.map.setView(params.center, params.zoom); } + + // set active alternative (if via points are set or alternative does not exists: automatic fallback to shortest route) + OSRM.G.active_alternative = params.active_alternative; // compute route - OSRM.Routing.getRoute(); + OSRM.Routing.getRoute({keepAlternative:true}); OSRM.G.initial_position_override = true; return; } @@ -280,4 +290,4 @@ OSRM.inMaintenance = function(){ }; // onload event -OSRM.Browser.onLoadHandler( OSRM.init ); \ No newline at end of file +OSRM.Browser.onLoadHandler( OSRM.init ); diff --git a/WebContent/printing/OSRM.Printing.js b/WebContent/printing/OSRM.Printing.js index 081f1b8bf..212a7ea20 100644 --- a/WebContent/printing/OSRM.Printing.js +++ b/WebContent/printing/OSRM.Printing.js @@ -187,13 +187,17 @@ show: function(response) { // draw route & query for better geometry print_window.OSRM.drawRoute( positions ); OSRM.JSONP.call(OSRM.Routing._buildCall()+'&z='+zoom+'&instructions=false', OSRM.Printing.drawRoute, OSRM.Printing.timeoutRoute, OSRM.DEFAULTS.JSONP_TIMEOUT, 'print'); - // NOTE: simply appended correct zoom level as second zoom parameter to JSONP call -> OSRM API only considers the last one! + // NOTE: correct zoom level was appended as second zoom parameter to JSONP call -> OSRM API only considers the last one! }, timeoutRoute: function() {}, drawRoute: function(response) { if(!response) return; - var positions = OSRM.RoutingGeometry._decode(response.route_geometry, 5); + + response.alternative_geometries.unshift( response.route_geometry ); + if( OSRM.G.active_alternative >= response.alternative_geometries.length ) // no redraw if the selected alternative cannot be found + return; + positions = OSRM.RoutingGeometry._decode( response.alternative_geometries[ OSRM.G.active_alternative ], 5 ); OSRM.G.printwindow.OSRM.drawRoute( positions ); }, diff --git a/WebContent/routing/OSRM.Routing.js b/WebContent/routing/OSRM.Routing.js index 5c2cd2bf5..94ea5fde3 100644 --- a/WebContent/routing/OSRM.Routing.js +++ b/WebContent/routing/OSRM.Routing.js @@ -57,6 +57,8 @@ timeoutRoute_Reversed: function() { showRoute: function(response, parameters) { if(!response) return; + if(!parameters || parameters.keepAlternative == false) + OSRM.G.active_alternative = 0; OSRM.G.response = response; // needed for printing & history routes! if(response.status == 207) { @@ -65,9 +67,10 @@ showRoute: function(response, parameters) { OSRM.RoutingDescription.showNA( OSRM.loc("NO_ROUTE_FOUND") ); OSRM.Routing._snapRoute(); } else { - OSRM.RoutingGeometry.show(response); - OSRM.RoutingNoNames.show(response); - OSRM.RoutingDescription.show(response); + OSRM.RoutingAlternatives.prepare(OSRM.G.response); + OSRM.RoutingGeometry.show(OSRM.G.response); + OSRM.RoutingNoNames.show(OSRM.G.response); + OSRM.RoutingDescription.show(OSRM.G.response); OSRM.Routing._snapRoute(); } OSRM.Routing._updateHints(response); @@ -95,14 +98,17 @@ showRoute_Dragging: function(response) { if(OSRM.G.pending) setTimeout(OSRM.Routing.draggingTimeout,1); }, -showRoute_Redraw: function(response) { +showRoute_Redraw: function(response, parameters) { if(!response) return; + if(!parameters || parameters.keepAlternative == false) + OSRM.G.active_alternative = 0; - //OSRM.G.response = response; // not needed, even harmful as important information is not stored! + OSRM.G.response = response; // not needed, even harmful as important information is not stored! ==> really ???? if(response.status != 207) { - OSRM.RoutingGeometry.show(response); - OSRM.RoutingNoNames.show(response); + OSRM.RoutingAlternatives.prepare(OSRM.G.response); + OSRM.RoutingGeometry.show(OSRM.G.response); + OSRM.RoutingNoNames.show(OSRM.G.response); } OSRM.Routing._updateHints(response); }, @@ -132,13 +138,13 @@ getRoute_Reversed: function() { OSRM.JSONP.clear('route'); OSRM.JSONP.call(OSRM.Routing._buildCall()+'&instructions=true', OSRM.Routing.showRoute, OSRM.Routing.timeoutRoute_Reversed, OSRM.DEFAULTS.JSONP_TIMEOUT, 'route'); }, -getRoute_Redraw: function() { +getRoute_Redraw: function(parameters) { if( OSRM.G.markers.route.length < 2 ) return; OSRM.JSONP.clear('dragging'); OSRM.JSONP.clear('redraw'); - OSRM.JSONP.call(OSRM.Routing._buildCall()+'&instructions=true', OSRM.Routing.showRoute_Redraw, OSRM.Routing.timeoutRoute, OSRM.DEFAULTS.JSONP_TIMEOUT, 'redraw'); + OSRM.JSONP.call(OSRM.Routing._buildCall()+'&instructions=true', OSRM.Routing.showRoute_Redraw, OSRM.Routing.timeoutRoute, OSRM.DEFAULTS.JSONP_TIMEOUT, 'redraw',parameters); }, getRoute_Dragging: function() { OSRM.G.pending = !OSRM.JSONP.call(OSRM.Routing._buildCall()+'&instructions=false', OSRM.Routing.showRoute_Dragging, OSRM.Routing.timeoutRoute_Dragging, OSRM.DEFAULTS.JSONP_TIMEOUT, 'dragging');; diff --git a/WebContent/routing/OSRM.RoutingAlternatives.js b/WebContent/routing/OSRM.RoutingAlternatives.js new file mode 100644 index 000000000..c608f6831 --- /dev/null +++ b/WebContent/routing/OSRM.RoutingAlternatives.js @@ -0,0 +1,127 @@ +/* +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU AFFERO General Public License as published by +the Free Software Foundation; either version 3 of the License, or +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +or see http://www.gnu.org/licenses/agpl.txt. +*/ + +// OSRM routing alternatives +// [everything about handling alternatives] + + +OSRM.RoutingAlternatives = { + +// data of gui buttons for alternativess +_buttons: [ + {id:"gui-a", label:"A"}, + {id:"gui-b", label:"B"} +], + +// initialize required values +init: function() { + OSRM.G.active_alternative = 0; + OSRM.G.alternative_count = 0; +}, + +// restructure response data +prepare: function(response) { + // move best route to alternative array + var the_response = OSRM.G.response; + the_response.alternative_geometries.unshift( response.route_geometry ); + the_response.alternative_instructions.unshift( response.route_instructions ); + the_response.alternative_summaries.unshift( response.route_summary ); + + // update basic information + OSRM.G.alternative_count = response.alternative_geometries.length; + if( OSRM.G.active_alternative >= OSRM.G.alternative_count ) // reset if the selected alternative cannot be found + OSRM.G.active_alternative = 0; + + // switch data + the_response.route_geometry = the_response.alternative_geometries[OSRM.G.active_alternative]; + the_response.route_instructions = the_response.alternative_instructions[OSRM.G.active_alternative]; + the_response.route_summary = the_response.alternative_summaries[OSRM.G.active_alternative]; +}, + +// switch active alternative and redraw buttons accordingly +setActive: function(button_id) { + // switch active alternative + OSRM.G.active_alternative = button_id; + + // redraw clickable buttons + var buttons = OSRM.RoutingAlternatives._buttons; + for(var i=0, size=OSRM.G.alternative_count; i'+buttons[i].label+'' + data; + } + // draw non-clickable buttons + for(var i=OSRM.G.alternative_count, size=buttons.length; i'+buttons[i].label+'' + data; + } + // add buttons to DOM + document.getElementById('information-box-header').innerHTML = data + document.getElementById('information-box-header').innerHTML; + + // add events + for(var i=0, size=OSRM.G.alternative_count; i