diff --git a/WebContent/OSRM.base.js b/WebContent/OSRM.base.js
index 492f210c0..783282ae4 100644
--- a/WebContent/OSRM.base.js
+++ b/WebContent/OSRM.base.js
@@ -26,32 +26,3 @@ OSRM.DEFAULTS = {};
OSRM.GLOBALS = {};
OSRM.G = OSRM.GLOBALS; // abbreviations
OSRM.C = OSRM.CONSTANTS;
-
-
-// declare one class to be a subclass of another class
-// (runs anonymous function to prevent local functions cluttering global namespace)
-(function() {
-var _inheritFromHelper = function() {};
-OSRM.inheritFrom = function( sub_class, base_class ) {
- _inheritFromHelper.prototype = base_class.prototype;
- sub_class.prototype = new _inheritFromHelper();
- sub_class.prototype.constructor = sub_class;
- sub_class.prototype.base = base_class.prototype;
-};
-}());
-
-
-// extend prototypes of a class -> used to add member values and functions
-OSRM.extend = function( target_class, properties ) {
- for( property in properties ) {
- target_class.prototype[property] = properties[property];
- }
-};
-
-
-// [usage of convenience functions]
-// SubClass = function() {
-// SubClass.prototype.base.constructor.apply(this, arguments);
-// }
-// OSRM.inheritFrom( SubClass, BaseClass );
-// OSRM.extend( SubClass, { property:value } );
diff --git a/WebContent/base/OSRM.Geocoder.js b/WebContent/base/OSRM.Geocoder.js
new file mode 100644
index 000000000..4790f734d
--- /dev/null
+++ b/WebContent/base/OSRM.Geocoder.js
@@ -0,0 +1,217 @@
+/*
+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 geocoding routines
+// [geocoder query, management and display of geocoder results]
+
+// some constants
+OSRM.CONSTANTS.SOURCE_LABEL = "source";
+OSRM.CONSTANTS.TARGET_LABEL = "target";
+OSRM.CONSTANTS.VIA_LABEL = "via";
+OSRM.CONSTANTS.DO_FALLBACK_TO_LAT_LNG = true;
+
+
+OSRM.Geocoder = {
+
+//[normal geocoding]
+
+// process input request and call geocoder if needed
+call: function(marker_id, query) {
+ if(query=="")
+ return;
+
+ //geo coordinates given -> directly draw results
+ if(query.match(/^\s*[-+]?[0-9]*\.?[0-9]+\s*[,;]\s*[-+]?[0-9]*\.?[0-9]+\s*$/)){
+ var coord = query.split(/[,;]/);
+ OSRM.Geocoder._onclickResult(marker_id, coord[0], coord[1]);
+ OSRM.Geocoder.updateAddress( marker_id );
+ return;
+ }
+
+ //build request for geocoder
+ var call = OSRM.DEFAULTS.HOST_GEOCODER_URL + "?format=json&json_callback=%jsonp" + OSRM.DEFAULTS.GEOCODER_BOUNDS + "&accept-language="+OSRM.Localization.current_language+"&q=" + query;
+ OSRM.JSONP.call( call, OSRM.Geocoder._showResults, OSRM.Geocoder._showResults_Timeout, OSRM.DEFAULTS.JSONP_TIMEOUT, "geocoder_"+marker_id, {marker_id:marker_id,query:query} );
+},
+
+
+// helper function for clicks on geocoder search results
+_onclickResult: function(marker_id, lat, lon) {
+ var index;
+ if( marker_id == OSRM.C.SOURCE_LABEL )
+ index = OSRM.G.markers.setSource( new L.LatLng(lat, lon) );
+ else if( marker_id == OSRM.C.TARGET_LABEL )
+ index = OSRM.G.markers.setTarget( new L.LatLng(lat, lon) );
+ else
+ return;
+
+ OSRM.G.markers.route[index].show();
+ OSRM.G.markers.route[index].centerView();
+ if( OSRM.G.markers.route.length > 1 )
+ OSRM.Routing.getRoute();
+},
+
+
+// process geocoder response
+_showResults: function(response, parameters) {
+ if(!response){
+ OSRM.Geocoder._showResults_Empty(parameters);
+ return;
+ }
+
+ if(response.length == 0) {
+ OSRM.Geocoder._showResults_Empty(parameters);
+ return;
+ }
+
+ // show first result
+ OSRM.Geocoder._onclickResult(parameters.marker_id, response[0].lat, response[0].lon);
+ if( OSRM.G.markers.route.length > 1 ) // if a route is displayed, we don't need to show other possible geocoding results
+ return;
+
+ // show possible results for input
+ var html = "";
+ html += '
';
+ for(var i=0; i < response.length; i++){
+ var result = response[i];
+
+ //odd or even ?
+ var rowstyle='results-odd';
+ if(i%2==0) { rowstyle='results-even'; }
+
+ html += '';
+ html += ''+(i+1)+'. | ';
+ html += '';
+
+ if(result.display_name){
+ html += ' '+result.display_name+' ';
+ }
+ html += " |
";
+ }
+ html += '
';
+
+ document.getElementById('information-box-header').innerHTML =
+ "" +
+ "";
+ "";
+ document.getElementById('information-box').innerHTML = html;
+},
+_showResults_Empty: function(parameters) {
+ document.getElementById('information-box-header').innerHTML =
+ "" +
+ "";
+ if(parameters.marker_id == OSRM.C.SOURCE_LABEL)
+ document.getElementById('information-box').innerHTML = ""+OSRM.loc("NO_RESULTS_FOUND_SOURCE")+": "+parameters.query +"
";
+ else if(parameters.marker_id == OSRM.C.TARGET_LABEL)
+ document.getElementById('information-box').innerHTML = ""+OSRM.loc("NO_RESULTS_FOUND_TARGET")+": "+parameters.query +"
";
+ else
+ document.getElementById('information-box').innerHTML = ""+OSRM.loc("NO_RESULTS_FOUND")+": "+parameters.query +"
";
+},
+_showResults_Timeout: function() {
+ document.getElementById('information-box-header').innerHTML =
+ "" +
+ "";
+ document.getElementById('information-box').innerHTML = ""+OSRM.loc("TIMED_OUT")+"
";
+},
+
+
+// [reverse geocoding]
+
+//update geo coordinates in input boxes
+updateLocation: function(marker_id) {
+ if (marker_id == OSRM.C.SOURCE_LABEL && OSRM.G.markers.hasSource()) {
+ document.getElementById("gui-input-source").value = OSRM.G.markers.route[0].getLat().toFixed(6) + ", " + OSRM.G.markers.route[0].getLng().toFixed(6);
+ } else if (marker_id == OSRM.C.TARGET_LABEL && OSRM.G.markers.hasTarget()) {
+ document.getElementById("gui-input-target").value = OSRM.G.markers.route[OSRM.G.markers.route.length-1].getLat().toFixed(6) + ", " + OSRM.G.markers.route[OSRM.G.markers.route.length-1].getLng().toFixed(6);
+ }
+},
+
+
+// update address in input boxes
+updateAddress: function(marker_id, do_fallback_to_lat_lng) {
+ // build request for reverse geocoder
+ var lat = null;
+ var lng = null;
+
+ if(marker_id == OSRM.C.SOURCE_LABEL && OSRM.G.markers.hasSource()) {
+ lat = OSRM.G.markers.route[0].getLat();
+ lng = OSRM.G.markers.route[0].getLng();
+ } else if(marker_id == OSRM.C.TARGET_LABEL && OSRM.G.markers.hasTarget() ) {
+ lat = OSRM.G.markers.route[OSRM.G.markers.route.length-1].getLat();
+ lng = OSRM.G.markers.route[OSRM.G.markers.route.length-1].getLng();
+ } else
+ return;
+
+ var call = OSRM.DEFAULTS.HOST_REVERSE_GEOCODER_URL + "?format=json&json_callback=%jsonp" + "&accept-language="+OSRM.Localization.current_language + "&lat=" + lat + "&lon=" + lng;
+ OSRM.JSONP.call( call, OSRM.Geocoder._showReverseResults, OSRM.Geocoder._showReverseResults_Timeout, OSRM.DEFAULTS.JSONP_TIMEOUT, "reverse_geocoder_"+marker_id, {marker_id:marker_id, do_fallback: do_fallback_to_lat_lng} );
+},
+
+
+// processing JSONP response of reverse geocoder
+_showReverseResults: function(response, parameters) {
+ if(!response) {
+ OSRM.Geocoder._showReverseResults_Timeout(response, parameters);
+ return;
+ }
+
+ if(response.address == undefined) {
+ OSRM.Geocoder._showReverseResults_Timeout(response, parameters);
+ return;
+ }
+
+ // build reverse geocoding address
+ var used_address_data = 0;
+ var address = "";
+ if( response.address.road) {
+ address += response.address.road;
+ used_address_data++;
+ }
+ if( response.address.city ) {
+ if( used_address_data > 0 )
+ address += ", ";
+ address += response.address.city;
+ used_address_data++;
+ } else if( response.address.village ) {
+ if( used_address_data > 0 )
+ address += ", ";
+ address += response.address.village;
+ used_address_data++;
+ }
+ if( used_address_data < 2 && response.address.country ) {
+ if( used_address_data > 0 )
+ address += ", ";
+ address += response.address.country;
+ used_address_data++;
+ }
+ if( used_address_data == 0 ) {
+ OSRM.Geocoder._showReverseResults_Timeout(response, parameters);
+ return;
+ }
+
+ // add result to DOM
+ if(parameters.marker_id == OSRM.C.SOURCE_LABEL && OSRM.G.markers.hasSource() )
+ document.getElementById("gui-input-source").value = address;
+ else if(parameters.marker_id == OSRM.C.TARGET_LABEL && OSRM.G.markers.hasTarget() )
+ document.getElementById("gui-input-target").value = address;
+},
+_showReverseResults_Timeout: function(response, parameters) {
+ if(!parameters.do_fallback)
+ return;
+
+ OSRM.Geocoder.updateLocation(parameters.marker_id);
+}
+
+};
diff --git a/WebContent/base/OSRM.Map.js b/WebContent/base/OSRM.Map.js
new file mode 100644
index 000000000..31685234a
--- /dev/null
+++ b/WebContent/base/OSRM.Map.js
@@ -0,0 +1,103 @@
+/*
+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 map handling
+// [initialization, event handling, centering relative to UI]
+
+// will hold the map object
+OSRM.GLOBALS.map = null;
+
+
+// map controller
+// [map initialization, event handling]
+OSRM.Map = {
+
+// map initialization
+init: function() {
+ // check if GUI is initialized!
+ if(OSRM.GUI.visible == null)
+ OSRM.GUI.init();
+
+ // setup tile servers
+ var tile_servers = OSRM.DEFAULTS.TILE_SERVERS;
+ var base_maps = {};
+ for(var i=0, size=tile_servers.length; i routes are not hidden during zoom
+ fadeAnimation: false
+ });
+
+ // add layer control
+ var layersControl = new L.Control.Layers(base_maps, {});
+ OSRM.G.map.addControl(layersControl);
+
+ // move zoom markers
+ OSRM.Browser.getElementsByClassName(document,'leaflet-control-zoom')[0].style.left=(OSRM.GUI.width+10)+"px";
+ OSRM.Browser.getElementsByClassName(document,'leaflet-control-zoom')[0].style.top="5px";
+
+ // map events
+ OSRM.G.map.on('zoomend', OSRM.Map.zoomed );
+ OSRM.G.map.on('click', OSRM.Map.click );
+ OSRM.G.map.on('contextmenu', OSRM.Map.contextmenu );
+ OSRM.G.map.on('mousemove', OSRM.Map.mousemove );
+},
+
+// init map position and zoom (respect UI visibility / use browser geolocation)
+initPosition: function() {
+ var position = new L.LatLng( OSRM.DEFAULTS.ONLOAD_LATITUDE, OSRM.DEFAULTS.ONLOAD_LONGITUDE);
+ OSRM.G.map.setViewUI( position, OSRM.DEFAULTS.ONLOAD_ZOOM_LEVEL, true);
+ if (navigator.geolocation && document.URL.indexOf("file://") == -1) // convenience: FF does not save access rights for local files
+ navigator.geolocation.getCurrentPosition(OSRM.Map.geolocationResponse);
+},
+
+// map event handlers
+zoomed: function(e) {
+ if(OSRM.G.dragging)
+ OSRM.Routing.getDragRoute();
+ else
+ OSRM.Routing.getZoomRoute();
+},
+contextmenu: function(e) {;},
+mousemove: function(e) { OSRM.Via.drawDragMarker(e); },
+click: function(e) {
+ if( !OSRM.G.markers.hasSource() ) {
+ var index = OSRM.G.markers.setSource( e.latlng );
+ OSRM.Geocoder.updateAddress( OSRM.C.SOURCE_LABEL, OSRM.C.DO_FALLBACK_TO_LAT_LNG );
+ OSRM.G.markers.route[index].show();
+ OSRM.G.markers.route[index].centerView( OSRM.G.map.getZoom() );
+ OSRM.Routing.getRoute();
+ } else if( !OSRM.G.markers.hasTarget() ) {
+ var index = OSRM.G.markers.setTarget( e.latlng );
+ OSRM.Geocoder.updateAddress( OSRM.C.TARGET_LABEL, OSRM.C.DO_FALLBACK_TO_LAT_LNG );
+ OSRM.G.markers.route[index].show();
+ OSRM.G.markers.route[index].centerView( OSRM.G.map.getZoom() );
+ OSRM.Routing.getRoute();
+ }
+},
+geolocationResponse: function(response) {
+ var latlng = new L.LatLng(response.coords.latitude, response.coords.longitude);
+ OSRM.G.map.setViewUI(latlng, OSRM.DEFAULTS.ZOOM_LEVEL );
+}
+};
diff --git a/WebContent/base/OSRM.Markers.js b/WebContent/base/OSRM.Markers.js
new file mode 100644
index 000000000..ccd2f975b
--- /dev/null
+++ b/WebContent/base/OSRM.Markers.js
@@ -0,0 +1,281 @@
+/*
+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 markers
+// [base marker class, derived highlight marker and route marker classes, marker management]
+
+
+// base marker class (wraps Leaflet markers)
+OSRM.Marker = function( label, style, position ) {
+ this.label = label ? label : "marker";
+ this.position = position ? position : new L.LatLng(0,0);
+
+ this.marker = new L.MouseMarker( this.position, style );
+ this.marker.parent = this;
+
+ this.shown = false;
+ this.hint = null;
+};
+OSRM.extend( OSRM.Marker,{
+show: function() {
+ OSRM.G.map.addLayer(this.marker);
+ this.shown = true;
+},
+hide: function() {
+ OSRM.G.map.removeLayer(this.marker);
+ this.shown = false;
+},
+setPosition: function( position ) {
+ this.position = position;
+ this.marker.setLatLng( position );
+ this.hint = null;
+},
+getPosition: function() {
+ return this.position;
+},
+getLat: function() {
+ return this.position.lat;
+},
+getLng: function() {
+ return this.position.lng;
+},
+isShown: function() {
+ return this.shown;
+},
+centerView: function(zoom) {
+ if( zoom == undefined )
+ zoom = OSRM.DEFAULTS.ZOOM_LEVEL;
+ OSRM.G.map.setViewUI( this.position, zoom );
+},
+toString: function() {
+ return "OSRM.Marker: \""+this.label+"\", "+this.position+")";
+}
+});
+
+
+// route marker class (draggable, invokes route drawing routines)
+OSRM.RouteMarker = function ( label, style, position ) {
+ style.baseicon = style.icon;
+ OSRM.RouteMarker.prototype.base.constructor.apply( this, arguments );
+ this.label = label ? label : "route_marker";
+
+ this.marker.on( 'click', this.onClick );
+ this.marker.on( 'drag', this.onDrag );
+ this.marker.on( 'dragstart', this.onDragStart );
+ this.marker.on( 'dragend', this.onDragEnd );
+};
+OSRM.inheritFrom( OSRM.RouteMarker, OSRM.Marker );
+OSRM.extend( OSRM.RouteMarker, {
+onClick: function(e) {
+ for( var i=0; i1)
+ OSRM.Routing.getDragRoute();
+ OSRM.Geocoder.updateLocation( this.parent.label );
+},
+onDragStart: function(e) {
+ OSRM.G.dragging = true;
+ this.switchIcon(this.options.dragicon);
+
+ // store id of dragged marker
+ for( var i=0; i this.route.length-2 )
+ return -1;
+
+ this.route.splice(id+1,0, new OSRM.RouteMarker(OSRM.C.VIA_LABEL, {draggable:true,icon:OSRM.G.icons['marker-via'],dragicon:OSRM.G.icons['marker-via-drag']}, position));
+ return id+1;
+},
+removeMarker: function(id) {
+ if( id >= this.route.length )
+ return;
+
+ // also remove vias if source or target are removed
+ if( id==0 && this.route[0].label == OSRM.C.SOURCE_LABEL ) {
+ this.removeVias();
+ document.getElementById('gui-input-source').value = "";
+ document.getElementById('information-box').innerHTML = "";
+ document.getElementById('information-box-header').innerHTML = "";
+ document.getElementById('gui-delete-source').style.visibility = "hidden";
+ } else if( id == this.route.length-1 && this.route[ this.route.length-1 ].label == OSRM.C.TARGET_LABEL ) {
+ this.removeVias();
+ id = this.route.length-1;
+ document.getElementById('gui-input-target').value = "";
+ document.getElementById('information-box').innerHTML = "";
+ document.getElementById('information-box-header').innerHTML = "";
+ document.getElementById('gui-delete-target').style.visibility = "hidden";
+ }
+
+ this.route[id].hide();
+ this.route.splice(id, 1);
+},
+reverseMarkers: function() {
+ var size = this.route.length;
+
+ // invert route, if a route is shown
+ if( size > 1 ) {
+ // switch positions in nodes
+ var temp_position = this.route[0].getPosition();
+ this.route[0].setPosition( this.route[size-1].getPosition() );
+ OSRM.G.markers.route[size-1].setPosition( temp_position );
+ // switch nodes in array
+ var temp_node = OSRM.G.markers.route[0];
+ OSRM.G.markers.route[0] = OSRM.G.markers.route[size-1];
+ OSRM.G.markers.route[size-1] = temp_node;
+ // reverse route
+ OSRM.G.markers.route.reverse();
+ // clear information (both delete markers stay visible)
+ document.getElementById('information-box').innerHTML = "";
+ document.getElementById('information-box-header').innerHTML = "";
+
+ // invert marker, if only one marker is shown (implicit clear of information / delete markers)
+ } else if( size > 0 ) {
+ var position = this.route[0].getPosition();
+ var label = this.route[0].label;
+ this.removeMarker(0);
+ if( label == OSRM.C.TARGET_LABEL )
+ this.setSource( position );
+ else if( label == OSRM.C.SOURCE_LABEL )
+ this.setTarget( position );
+ this.route[0].show();
+ }
+
+},
+hasSource: function() {
+ if( OSRM.G.markers.route[0] && OSRM.G.markers.route[0].label == OSRM.C.SOURCE_LABEL )
+ return true;
+ return false;
+},
+hasTarget: function() {
+ if( OSRM.G.markers.route[OSRM.G.markers.route.length-1] && OSRM.G.markers.route[OSRM.G.markers.route.length-1].label == OSRM.C.TARGET_LABEL )
+ return true;
+ return false;
+}
+});
diff --git a/WebContent/base/OSRM.Route.js b/WebContent/base/OSRM.Route.js
new file mode 100644
index 000000000..54a1097e8
--- /dev/null
+++ b/WebContent/base/OSRM.Route.js
@@ -0,0 +1,193 @@
+/*
+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 routes
+// [drawing of all types of route geometry]
+
+
+// simple route class (wraps Leaflet Polyline)
+OSRM.SimpleRoute = function (label, style) {
+ this.label = (label ? label : "route");
+ this.route = new L.DashedPolyline();
+ this.route.setLatLngs( [] );
+ if(style) this.route.setStyle( style );
+
+ this.shown = false;
+};
+OSRM.extend( OSRM.SimpleRoute,{
+show: function() {
+ OSRM.G.map.addLayer(this.route);
+ this.shown = true;
+},
+hide: function() {
+ OSRM.G.map.removeLayer(this.route);
+ this.shown = false;
+},
+isShown: function() {
+ return this.shown;
+},
+getPoints: function() {
+ return this.route._originalPoints;
+},
+getPositions: function() {
+ return this.route.getLatLngs();
+},
+setPositions: function(positions) {
+ this.route.setLatLngs( positions );
+},
+setStyle: function(style) {
+ this.route.setStyle(style);
+},
+centerView: function() {
+ var bounds = new L.LatLngBounds( this.getPositions() );
+ OSRM.g.map.fitBoundsUI( bounds );
+},
+toString: function() {
+ return "OSRM.Route("+ this.label + ", " + this.route.getLatLngs().length + " points)";
+}
+});
+
+
+// multiroute class (wraps Leaflet LayerGroup to hold several disjoint routes)
+OSRM.MultiRoute = function (label) {
+ this.label = (label ? label : "multiroute");
+ this.route = new L.LayerGroup();
+
+ this.shown = false;
+};
+OSRM.extend( OSRM.MultiRoute,{
+show: function() {
+ OSRM.G.map.addLayer(this.route);
+ this.shown = true;
+},
+hide: function() {
+ OSRM.G.map.removeLayer(this.route);
+ this.shown = false;
+},
+isShown: function() {
+ return this.shown;
+},
+addRoute: function(positions) {
+ var line = new L.DashedPolyline( positions );
+ line.on('click', function(e) { OSRM.G.route.fire('click',e); });
+ this.route.addLayer( line );
+},
+clearRoutes: function() {
+ this.route.clearLayers();
+},
+setStyle: function(style) {
+ this.route.invoke('setStyle', style);
+},
+toString: function() {
+ return "OSRM.MultiRoute("+ this.label + ")";
+}
+});
+
+
+// route management (handles drawing of route geometry - current route, old route, unnamed route, highlight unnamed streets)
+// [this holds the route geometry]
+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_style = {dashed:false,color:'#0033FF', weight:5};
+ this._current_noroute_style = {dashed:true, color:'#222222', weight:2};
+ this._old_route_style = {dashed:false,color:'#112233', weight:5};
+ 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._noroute = OSRM.Route.ROUTE;
+};
+OSRM.Route.NOROUTE = true;
+OSRM.Route.ROUTE = false;
+OSRM.extend( OSRM.Route,{
+
+ showRoute: function(positions, noroute) {
+ this._noroute = noroute;
+ this._current_route.setPositions( positions );
+ if ( this._noroute == OSRM.Route.NOROUTE )
+ this._current_route.setStyle( this._current_noroute_style );
+ else
+ this._current_route.setStyle( this._current_route_style );
+ this._current_route.show();
+ //this._raiseUnnamedRoute();
+ },
+ hideRoute: function() {
+ this._current_route.hide();
+ this._unnamed_route.hide();
+ },
+ hideAll: function() {
+ this._current_route.hide();
+ this._unnamed_route.hide();
+ this._old_route.hide();
+ this._noroute = OSRM.Route.ROUTE;
+ },
+
+ showUnnamedRoute: function(positions) {
+ this._unnamed_route.clearRoutes();
+ for(var i=0; i easier way in will be available Leaflet 0.4
+ _raiseUnnamedRoute: function() {
+ if(this._unnamed_route.isShown()) {
+ this._unnamed_route.hide();
+ this._unnamed_route.show();
+ }
+ },
+ showOldRoute: function() {
+ this._old_route.setPositions( this._current_route.getPositions() );
+ if ( this._noroute == OSRM.Route.NOROUTE)
+ this._old_route.setStyle( this._old_noroute_style );
+ else
+ this._old_route.setStyle( this._old_route_style );
+ this._old_route.show();
+ this._raiseUnnamedRoute();
+ // change color of unnamed route highlighting - no separate object as dragged route does not have unnamed route highlighting
+ this._unnamed_route.setStyle( this._old_unnamed_route_style );
+ },
+ hideOldRoute: function() {
+ this._old_route.hide();
+ },
+
+ isShown: function() {
+ return this._current_route.isShown();
+ },
+ isRoute: function() {
+ return !(this._noroute);
+ },
+ getPositions: function() {
+ return this._current_route.getPositions();
+ },
+ getPoints: function() {
+ return this._current_route.getPoints();
+ },
+ fire: function(type,event) {
+ this._current_route.route.fire(type,event);
+ },
+ centerView: function() {
+ this._current_route.centerView();
+ }
+});
diff --git a/WebContent/base/OSRM.Via.js b/WebContent/base/OSRM.Via.js
new file mode 100644
index 000000000..9775d3b3d
--- /dev/null
+++ b/WebContent/base/OSRM.Via.js
@@ -0,0 +1,121 @@
+/*
+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 via marker routines
+// [find correct position for a via marker]
+
+// store location of via points returned by server
+OSRM.GLOBALS.via_points = [];
+
+
+OSRM.Via = {
+
+// find route segment of current route geometry that is closest to the new via node (marked by index of its endpoint)
+_findNearestRouteSegment: function( new_via ) {
+ var min_dist = Number.MAX_VALUE;
+ var min_index = undefined;
+
+ var p = OSRM.G.map.latLngToLayerPoint( new_via );
+ var positions = OSRM.G.route.getPoints();
+ for(var i=1; i nearest_index) {
+ new_via_index = i;
+ break;
+ }
+ }
+
+ // add via node
+ return new_via_index;
+},
+
+
+//function that draws a drag marker
+dragTimer: new Date(),
+
+drawDragMarker: function(event) {
+ if( OSRM.G.route.isShown() == false)
+ return;
+ if( OSRM.G.dragging == true )
+ return;
+
+ // throttle computation
+ if( (new Date() - OSRM.Via.dragTimer) < 25 )
+ return;
+ OSRM.Via.dragTimer = new Date();
+
+ // get distance to route
+ var minpoint = OSRM.G.route._current_route.route.closestLayerPoint( event.layerPoint );
+ var min_dist = minpoint ? minpoint._sqDist : 1000;
+
+ // get distance to markers
+ var mouse = event.latlng;
+ for(var i=0, size=OSRM.G.markers.route.length; i 0) {
+ t = ((p.x - x) * dx + (p.y - y) * dy) / dot;
+
+ if (t > 1) {
+ x = p2.x;
+ y = p2.y;
+ } else if (t > 0) {
+ x += dx * t;
+ y += dy * t;
+ }
+ }
+
+ dx = p.x - x;
+ dy = p.y - y;
+
+ // DS_CHANGE: modified return values
+ if(sqDist)
+ return dx*dx + dy*dy;
+ else {
+ var p = new L.Point(x,y);
+ p._sqDist = dx*dx + dy*dy;
+ return p;
+ }
+};
+
+
+// makes requestAnimFrame respect the immediate paramter -> prevents drag events after dragend events
+// (alternatively: add if(!this.dragging ) return to L.Draggable._updatePosition, but must be done in leaflet.js!)
+// [TODO: In Leaflet 0.4 use L.Util.cancelAnimFrame(this._animRequest) in L.Draggable._onUp() instead, also has to be done in leaflet.js!]
+L.Util.requestAnimFrame = (function () {
+ function timeoutDefer(callback) {
+ window.setTimeout(callback, 1000 / 60);
+ }
+
+ var requestFn = window.requestAnimationFrame ||
+ window.webkitRequestAnimationFrame ||
+ window.mozRequestAnimationFrame ||
+ window.oRequestAnimationFrame ||
+ window.msRequestAnimationFrame ||
+ timeoutDefer;
+
+ return function (callback, context, immediate, contextEl) {
+ callback = context ? L.Util.bind(callback, context) : callback;
+ if (immediate ) { // DS_CHANGE: removed additional condition requestFn === timeoutDefer
+ callback();
+ } else {
+ requestFn(callback, contextEl);
+ }
+ };
+}());
diff --git a/WebContent/gui/leaflet/L.DashedPolyline.js b/WebContent/gui/leaflet/L.DashedPolyline.js
new file mode 100644
index 000000000..875d89ce6
--- /dev/null
+++ b/WebContent/gui/leaflet/L.DashedPolyline.js
@@ -0,0 +1,60 @@
+/*
+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.
+*/
+
+// Leaflet extension: Dashed Polyline
+// [adds dashed optionally dashed lines when using SVG or VML rendering]
+
+
+// dashed polyline class
+L.DashedPolyline = L.Polyline.extend({
+ initialize: function(latlngs, options) {
+ L.Polyline.prototype.initialize.call(this, latlngs, options);
+ },
+
+ options: {
+ dashed: true
+ }
+});
+
+
+// svg rendering
+L.DashedPolyline = !L.Browser.svg ? L.DashedPolyline : L.DashedPolyline.extend({
+ _updateStyle: function () {
+ L.Polyline.prototype._updateStyle.call(this);
+ if (this.options.stroke) {
+ if (this.options.dashed == true)
+ this._path.setAttribute('stroke-dasharray', '8,6');
+ else
+ this._path.setAttribute('stroke-dasharray', '');
+ }
+ }
+});
+
+
+// vml rendering
+L.DashedPolyline = L.Browser.svg || !L.Browser.vml ? L.DashedPolyline : L.DashedPolyline.extend({
+ _updateStyle: function () {
+ L.Polyline.prototype._updateStyle.call(this);
+ if (this.options.stroke) {
+ if (this.options.dashed == true)
+ this._stroke.dashstyle = "dash";
+ else
+ this._stroke.dashstyle = "solid";
+ }
+ }
+
+});
diff --git a/WebContent/gui/leaflet/L.MouseMarker.js b/WebContent/gui/leaflet/L.MouseMarker.js
new file mode 100644
index 000000000..f15c79b19
--- /dev/null
+++ b/WebContent/gui/leaflet/L.MouseMarker.js
@@ -0,0 +1,65 @@
+/*
+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.
+*/
+
+// Leaflet extension: MouseMarker
+// [marker class that propagates modifier and button presses in mouse click events and allows for changing icons]
+
+
+// extended marker class
+L.MouseMarker = L.Marker.extend({
+ initialize: function (latlng, options) {
+ L.Marker.prototype.initialize.apply(this, arguments);
+ },
+
+ switchIcon: function( icon ) {
+ this.options.icon = icon;
+
+ if (this._map) {
+ this._changeIcon();
+ this._reset();
+ }
+ },
+
+ _changeIcon: function () {
+ var options = this.options;
+
+ if (this._icon) {
+ this._icon = options.icon.switchIcon( this._icon );
+ if (this.options.clickable) // TODO: only needed until Leaflet 0.4
+ this._icon.className += ' leaflet-clickable';
+ }
+
+ var panes = this._map._panes;
+
+ if (this._shadow)
+ panes.shadowPane.removeChild(this._shadow);
+ this._shadow = options.icon.createShadow();
+ if (this._shadow)
+ panes.shadowPane.appendChild(this._shadow);
+ },
+
+ _onMouseClick: function (e) {
+ L.DomEvent.stopPropagation(e);
+ if (this.dragging && this.dragging.moved()) { return; }
+ this.fire(e.type, {
+ altKey: e.altKey,
+ ctrlKey: e.ctrlKey,
+ shiftKey: e.shiftKey,
+ button: e.button
+ });
+ }
+});
\ No newline at end of file
diff --git a/WebContent/gui/leaflet/L.SwitchableIcon.js b/WebContent/gui/leaflet/L.SwitchableIcon.js
new file mode 100644
index 000000000..8a93d863e
--- /dev/null
+++ b/WebContent/gui/leaflet/L.SwitchableIcon.js
@@ -0,0 +1,115 @@
+/*
+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.
+*/
+
+// Leaflet extension: SwitchableIcon
+// [will be an extension of L.Icon in Leaflet 0.4, for now it is a copy with added functionality]
+
+
+// icon class with functions to simply switch the icon images
+L.SwitchableIcon = L.Class.extend({
+ options: {
+ /*
+ iconUrl: (String) (required)
+ iconSize: (Point) (can be set through CSS)
+ iconAnchor: (Point) (centered by default if size is specified, can be set in CSS with negative margins)
+ popupAnchor: (Point) (if not specified, popup opens in the anchor point)
+ shadowUrl: (Point) (no shadow by default)
+ shadowSize: (Point)
+ */
+ className: ''
+ },
+
+ initialize: function (options) {
+ L.Util.setOptions(this, options);
+ },
+
+ createIcon: function () {
+ return this._createIcon('icon');
+ },
+
+ createShadow: function () {
+ return this.options.shadowUrl ? this._createIcon('shadow') : null;
+ },
+
+ _createIcon: function (name) {
+ var img = this._createImg(this.options[name + 'Url']);
+ this._setIconStyles(img, name);
+ return img;
+ },
+
+ _setIconStyles: function (img, name) {
+ var options = this.options,
+ size = options[name + 'Size'],
+ anchor = options.iconAnchor;
+
+ if (!anchor && size) {
+ anchor = size.divideBy(2, true);
+ }
+
+ if (name === 'shadow' && anchor && options.shadowOffset) {
+ anchor._add(options.shadowOffset);
+ }
+
+ img.className = 'leaflet-marker-' + name + ' ' + options.className;
+
+ if (anchor) {
+ img.style.marginLeft = (-anchor.x) + 'px';
+ img.style.marginTop = (-anchor.y) + 'px';
+ }
+
+ if (size) {
+ img.style.width = size.x + 'px';
+ img.style.height = size.y + 'px';
+ }
+ },
+
+ _createImg: function (src) {
+ var el;
+ if (!L.Browser.ie6) {
+ el = document.createElement('img');
+ el.src = src;
+ } else {
+ el = document.createElement('div');
+ el.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + src + '")';
+ }
+ return el;
+ },
+
+ // new functions start here
+ switchIcon: function (el) {
+ return this._switchIcon('icon', el);
+ },
+
+ switchShadow: function (el) {
+ return this.options.shadowUrl ? this._switchIcon('shadow', el) : null;
+ },
+
+ _switchIcon: function (name, el) {
+ var img = this._switchImg(this.options[name + 'Url'], el);
+ this._setIconStyles(img, name);
+ return img;
+ },
+
+ _switchImg: function (src, el) {
+ if (!L.Browser.ie6) {
+ el.src = src;
+ } else {
+ el.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + src + '")';
+ }
+ return el;
+ }
+});
diff --git a/WebContent/gui/leaflet/OSRM.MapView.js b/WebContent/gui/leaflet/OSRM.MapView.js
new file mode 100644
index 000000000..3492fe93a
--- /dev/null
+++ b/WebContent/gui/leaflet/OSRM.MapView.js
@@ -0,0 +1,54 @@
+/*
+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.
+*/
+
+// map view/model
+// [extending Leaflet L.Map with setView/fitBounds methods that respect UI visibility]
+L.MapView = L.Map.extend({
+ setViewUI: function(position, zoom, no_animation) {
+ if( OSRM.GUI.visible == true ) {
+ var point = this.project( position, zoom);
+ point.x-=OSRM.GUI.width/2;
+ position = this.unproject(point,zoom);
+ }
+ this.setView( position, zoom, no_animation);
+ },
+ fitBoundsUI: function(bounds) {
+ var southwest = bounds.getSouthWest();
+ var northeast = bounds.getNorthEast();
+ var zoom = this.getBoundsZoom(bounds);
+ var sw_point = this.project( southwest, zoom);
+ if( OSRM.GUI.visible == true )
+ sw_point.x-=OSRM.GUI.width+20;
+ else
+ sw_point.x-=20;
+ sw_point.y+=20;
+ var ne_point = this.project( northeast, zoom);
+ ne_point.y-=20;
+ sw_point.x+=20;
+ bounds.extend( this.unproject(sw_point,zoom) );
+ bounds.extend( this.unproject(ne_point,zoom) );
+ this.fitBounds( bounds );
+ },
+ getCenterUI: function(unbounded) {
+ var viewHalf = this.getSize();
+ if( OSRM.GUI.visible == true )
+ viewHalf.x += OSRM.GUI.width;
+ var centerPoint = this._getTopLeftPoint().add(viewHalf.divideBy(2));
+
+ return this.unproject(centerPoint, this._zoom, unbounded);
+ }
+});
diff --git a/WebContent/main.html b/WebContent/main.html
index 4e5c73267..8f0c4428b 100644
--- a/WebContent/main.html
+++ b/WebContent/main.html
@@ -36,35 +36,37 @@ or see http://www.gnu.org/licenses/agpl.txt.
-
-
-
-
+
+
+
+
+
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
diff --git a/WebContent/printing/printing.js b/WebContent/printing/printing.js
index 8303bba42..37a3d845c 100644
--- a/WebContent/printing/printing.js
+++ b/WebContent/printing/printing.js
@@ -27,7 +27,7 @@ OSRM.G = OSRM.GLOBALS;
function initialize(tile_server) {
// setup map
var tile_layer = new L.TileLayer(tile_server.url, tile_server.options);
- OSRM.G.map = new OSRM.MapView("overview-map", {
+ OSRM.G.map = new L.MapView("overview-map", {
center: new L.LatLng(51.505, -0.09),
zoom: 13,
zoomAnimation: false,
diff --git a/WebContent/utils/OSRM.EventHandler.js b/WebContent/utils/OSRM.EventHandler.js
new file mode 100644
index 000000000..a43033505
--- /dev/null
+++ b/WebContent/utils/OSRM.EventHandler.js
@@ -0,0 +1,61 @@
+/*
+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 EventHandler
+// [adds simple event handling: other classes can derive from this class to acquire custom event handling]
+
+
+OSRM.EventHandler = function() {
+ this._listeners = {};
+};
+
+OSRM.extend( OSRM.EventHandler, {
+
+ // add listener
+ addListener: function(type, listener) {
+ if( this._listeners[type] == undefined)
+ this._listeners[type] = [];
+ this._listeners[type].push(listener);
+ },
+
+ //remove event listener
+ removeListener: function(type, listener) {
+ if( this._listeners[type] != undefined) {
+ for(var i=0; i= 100000){ return (parseInt(distance/1000))+' ' + 'km'; }
+ else if(distance >= 10000){ return (parseInt(distance/1000).toFixed(1))+' ' + 'km'; }
+ else if(distance >= 1000){ return (parseFloat(distance/1000).toFixed(2))+' ' + 'km'; }
+ else{ return distance+' ' + 'm'; }
+},
+
+
+// [verification routines]
+
+// verify angles
+isLatitude: function(value) {
+ if( value >=-90 && value <=90)
+ return true;
+ else
+ return false;
+},
+isLongitude: function(value) {
+ if( value >=-180 && value <=180)
+ return true;
+ else
+ return false;
+}
+
+};
\ No newline at end of file
diff --git a/WebContent/utils/OSRM.browsers.js b/WebContent/utils/OSRM.browsers.js
new file mode 100644
index 000000000..9247a60dd
--- /dev/null
+++ b/WebContent/utils/OSRM.browsers.js
@@ -0,0 +1,66 @@
+/*
+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 old/cross browser support
+// [browser detection and routines for old/cross browser support]
+
+
+// browser detection (runs anonymous function to prevent local variables cluttering global namespace)
+(function() {
+ var useragent = navigator.userAgent;
+
+ OSRM.Browser = {
+ FF3: useragent.search(/Firefox\/3/),
+ IE6_9: useragent.search(/MSIE (6|7|8|9)/)
+ };
+}());
+
+
+// compatibility tools
+
+//add document.head reference for older browsers
+document.head = document.head || document.getElementsByTagName('head')[0];
+
+// supply getElementsByClassName method for older browser
+OSRM.Browser.getElementsByClassName = function( node, classname ) {
+ var a = [];
+ var re = new RegExp('(^| )'+classname+'( |$)');
+ var els = node.getElementsByTagName("*");
+ for(var i=0,j=els.length; i used to add member values and functions
+OSRM.extend = function( target_class, properties ) {
+ for( property in properties ) {
+ target_class.prototype[property] = properties[property];
+ }
+};
+
+
+// [usage of convenience functions]
+// SubClass = function() {
+// SubClass.prototype.base.constructor.apply(this, arguments);
+// }
+// OSRM.inheritFrom( SubClass, BaseClass );
+// OSRM.extend( SubClass, { property:value } );
diff --git a/WebContent/utils/OSRM.debug.js b/WebContent/utils/OSRM.debug.js
new file mode 100644
index 000000000..bce76898a
--- /dev/null
+++ b/WebContent/utils/OSRM.debug.js
@@ -0,0 +1,66 @@
+/*
+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.
+*/
+
+// debug code for OSRM
+// [works better than console.log in older browsers and for logging event handling]
+
+OSRM.debug = {};
+
+
+// access functions
+OSRM.debug.log = function(text) {
+ OSRM.debug.content.innerHTML += text + "
";
+ OSRM.debug.content.scrollTop = OSRM.debug.content.scrollHeight;
+};
+OSRM.debug.clear = function() {
+ OSRM.debug.content.innerHTML = "";
+};
+
+
+// add elements to DOM
+OSRM.debug.init = function() {
+ //create DOM objects for debug output
+ var wrapper = document.createElement('div');
+ wrapper.id = "OSRM.debug-wrapper";
+ wrapper.className = "gui-wrapper";
+ wrapper.style.cssText = "width:410px;height:95%;top:5px;right:50px;";
+
+ var box = document.createElement('div');
+ box.id = "OSRM.debug-box";
+ box.className = "gui-box";
+ box.style.cssText = "width:390px;top:0px;bottom:0px;";
+
+ var clear = document.createElement('a');
+ clear.id = "OSRM.debug-clear";
+ clear.className = "button not-selectable";
+ clear.innerHTML = "clear";
+ clear.onclick = OSRM.debug.clear;
+
+ OSRM.debug.content= document.createElement('div');
+ OSRM.debug.content.id = "OSRM.debug-content";
+ OSRM.debug.content.style.cssText = "position:absolute;bottom:0px;top:20px;width:380px;font-size:11px;overflow:auto;margin:5px;";
+
+ // add elements
+ document.body.appendChild(wrapper);
+ wrapper.appendChild(box);
+ box.appendChild(clear);
+ box.appendChild(OSRM.debug.content);
+};
+
+
+// onload event
+OSRM.Browser.onLoadHandler( OSRM.debug.init );
\ No newline at end of file