]> git.openstreetmap.org Git - rails.git/blobdiff - app/assets/javascripts/routing.js.erb
Start work on second engine
[rails.git] / app / assets / javascripts / routing.js.erb
index 30846479d28c0f094cde40785ae01e5df6bdb4c1..4eb91fc7aaeb826be74cc6df777d8c3a9ccbe2e2 100644 (file)
@@ -7,7 +7,10 @@
        https://github.com/apmon/openstreetmap-website/blob/9755c3ae0a8d0684d43760f91dc864ff42d8477a/app/views/routing/start.js.erb
 
        *** draggable start/end markers
-       
+       *** click each part
+       *** translation (including all alerts and presentation)
+       *** export GPX
+       *** URL history (or do we consciously not want to support that?)
 */
 
 var TURN_INSTRUCTIONS=["",
@@ -46,6 +49,7 @@ OSM.Routing=function(map,name,jqSearch) {
        r.route_to=null;
        r.viaPoints=[];
        r.polyline=null;
+       r.chosenEngine=null;
 
        // Geocoding
 
@@ -73,10 +77,12 @@ OSM.Routing=function(map,name,jqSearch) {
        
        // Route-fetching UI
 
+       r.selectEngine=function(e) {
+               r.chosenEngine=r.engines[e.target.selectedIndex];
+       };
        r.requestRoute=function() {
                if (r.route_from && r.route_to) {
-                       var chosen=jqSearch.find('select.routing_engines :selected').val();
-                       r.engines[chosen].getRoute(true,[r.route_from,r.route_to]);
+                       r.chosenEngine.getRoute(true,[r.route_from,r.route_to]);
                        // then, when the route has been fetched, it'll call the engine's gotRoute function
                }
        };
@@ -85,26 +91,62 @@ OSM.Routing=function(map,name,jqSearch) {
        r.setPolyline=function(line) {
                if (r.polyline) map.removeLayer(r.polyline);
                r.polyline=L.polyline(line, ROUTING_POLYLINE).addTo(r.map);
-               // *** zoom to fit
+               r.map.fitBounds(r.polyline.getBounds());
        };
 
        // Take an array of directions and write it out
        // (we use OSRM's route_instructions format)
+       // *** translations?
        r.setItinerary=function(steps) {
+               // Create base table
                $("#content").removeClass("overlay-sidebar");
                $('#sidebar_content').empty();
-               var html="";
+               var html='<h2><a class="geolink" href="#" onclick="$(~.close_directions~).click();return false;"><span class="icon close"></span></a>Directions</h2>'.replace(/~/g,"'");
+               html+="<table id='turnbyturn' />";
+               $('#sidebar_content').html(html);
+               // Add each row
+               var cumulative=0;
                for (var i=0; i<steps.length; i++) {
-                       var s=steps[i];
-                       html+="<div class='route_step'>";
-                       html+=TURN_INSTRUCTIONS[s[0]] || s[0];
-                       html+=s[1];
-                       html+="</div>";
+                       var step=steps[i];
+                       var instCodes=step[0].split('-');
+                       // Assemble instruction text
+                       var instText="<b>"+(i+1)+".</b> ";
+                       instText+=TURN_INSTRUCTIONS[instCodes[0]];
+                       if (instCodes[1]) { instText+="exit "+instCodes[1]+" "; }
+                       if (instCodes[0]!=15) { instText+=step[1] ? "<b>"+step[1]+"</b>" : "(unnamed)"; }
+                       // Distance
+                       var dist=step[2];
+                       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"; }
+                       // Add to table
+                       var row=$("<tr class='turn'/>");
+                       row.append("<td class='direction i"+instCodes[0]+"'> ");
+                       row.append("<td class='instruction'>"+instText);
+                       row.append("<td class='distance'>"+dist);
+                       with ({num: i, dist: step[3]}) {
+                               row.on('click',function(e) { 
+                                       r.clickTurn(num, r.polyline.getLatLngs()[dist]);
+                               });
+                       };
+                       $('#turnbyturn').append(row);
+                       cumulative+=step[2];
                }
-        $('#sidebar_content').html(html);
+       };
+       r.clickTurn=function(num,latlng) {
+               L.popup().setLatLng(latlng).setContent("<p>"+(num+1)+"</p>").openOn(r.map);
        };
 
 
+       // Close all routing UI
+       
+       r.close=function() {
+               $("#content").addClass("overlay-sidebar");
+               if (r.polyline) map.removeLayer(r.polyline);
+       };
+
        // Add engines
        
        r.engines=[];
@@ -118,7 +160,7 @@ OSM.Routing=function(map,name,jqSearch) {
                // Add generic JSONP function
                engine.requestJSONP=function(url) {
                        var script = document.createElement('script');
-                       script.src = url+"&jsonp="+r.name+".engine"+this.subscript+".gotRoute";
+                       script.src = url+r.name+".engine"+this.subscript+".gotRoute";
                        // OSRM doesn't like non-alphanumeric, otherwise we could just do OSM.routing.engines["+engine.subscript+"].gotRoute
                        document.body.appendChild(script); 
                };
@@ -144,10 +186,14 @@ OSM.Routing=function(map,name,jqSearch) {
                                if (this._hints[pair]) url+= "&hint="+this._hints[pair];
                        }
                        if (final) url+="&instructions=true";
-                       this.requestJSONP(url);
+                       this.requestJSONP(url+"&jsonp=");
                },
                gotRoute: function(data) {
-                       // *** save hints
+                       if (data.status==207) {
+                               alert("Couldn't find route between those two places");
+                               return false;
+                       }
+                       // *** store hints
                        var line=L.PolylineUtil.decode(data.route_geometry);
                        for (i=0; i<line.length; i++) { line[i].lat/=10; line[i].lng/=10; }
                        r.setPolyline(line);
@@ -155,5 +201,36 @@ OSM.Routing=function(map,name,jqSearch) {
                }
        });
 
+       // CloudMade foot engine
+       // *** again, this should be shared from a Cloudmade library somewhere
+       // *** this API key is taken from some example code, not for real live use!
+       
+       r.addEngine({
+               name: 'Foot (CloudMade)',
+               draggable: true,
+               getRoute: function(final,points) {
+                       var url="http://routes.cloudmade.com/8ee2a50541944fb9bcedded5165f09d9/api/0.3/";
+                       var p=[];
+                       for (var i=0; i<points.length; i++) {
+                               p.push(points[i][0]);
+                               p.push(points[i][1]);
+                       }
+                       url+=p.join(',');
+                       url+="/foot.js";
+                       this.requestJSONP(url+"?callback=");
+               },
+               gotRoute: function(data) {
+                       console.log(data);
+                       // *** todo
+                       // *** will require some degree of refactoring because instruction text is pre-assembled
+                       // *** otherwise largely like OSRM (funny that)
+               }
+       });
+       
+       // *** add MapQuest
+       // *** add YOURS
+       // *** move into separate files
+       
+       r.chosenEngine=r.engines[0];
        return r;
 };