×

Discussion Board

Results 1 to 5 of 5
  1. #1
    Nokia Developer Expert
    Join Date
    Jul 2013
    Posts
    4

    Routing result box

    this is a question from amateur :)

    i have created a map using complete Context Menu,

    in the menu i have "direction from here" and "direction to here",

    what i want to know is how to displaying the Routing / direction result ?

    i didn't know what isthe real name of that tool, direction result what i mean is direction box


    regards

    bayu

  2. #2
    Regular Contributor
    Join Date
    Aug 2011
    Location
    Berlin
    Posts
    289

    Re: Routing result box

    There is no such component available currently, and unfortunately as of 2.2.4 the standard nokia.maps.routing.component.ContextMenuHandler, doesn't expose the calculated route, it just places a polyline on the map.
    I have created a workaround for this from combining a custom context menu with the advance routing example.

    The example is quite long, but can be broken down into several parts.

    • Firstly the current routing menu items are removed from the context menu.
    • Secondly two new menu items are added which calculate the start waypoint and end waypoint
    • If both start point and end point have been defined, a standard route calculation will be made.
    • Because this is my route I can expose the RouteResultSet - this is the variable called mapRoute.
    • All the route instrructions, mini markers and metric/imperial conversions come from the advance routing example - the information is held in two DOM nodes -
      • The summary information is replaced directly in <span id="ticker"> at the head of the page.
      • The individual route instructions are created in a list, an appended as a child of <span id="details"> at the bottom of the page.
    • The start and end points are then reset.
    • There is also a short section of tidy up code to remove markers, instructions and so on if a second route is calculated.


    I'll append an example below. Note that the styling in the example is very crude - you would have to add your own css to repeat the professional look from here.com.

    Your use case would be an excellent extension to the current functionality of the routing part of the context menu component. I have discussed this with the team internally, and asked that the RouteResultSet generated in the current component should be exposed to developers in a future release.

  3. #3
    Regular Contributor
    Join Date
    Aug 2011
    Location
    Berlin
    Posts
    289

    Re: Routing result box

    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
    <html>
    <head>
    		<script type="text/javascript" charset="UTF-8" src="http://api.maps.nokia.com/2.2.4/jsl.js?routing=auto"></script>
    		<title>Custom Routing from Context Menu</title>
    </head>
    <body>
    		<div style="top:0%; height:3%; position: absolute;">
    			<span id="ticker">&nbsp;</span>
    		</div>
    		<div id="map" style="top:3%; width:100%; height:65%; position: absolute;"></div>
    		<div style="top:68%; height:30%; position: absolute;"><span id="details">&nbsp;</span>
    		
    		</div>
    <script type="text/javascript">
    /*<![CDATA[*/ 	
    	
    
    (function () {  	
    
    /////////////////////////////////////////////////////////////////////////////////////
    // Don't forget to set your API credentials
    //
    // Replace with your appId and token which you can obtain when you 
    // register on http://api.developer.nokia.com/ 
    //
    			nokia.Settings.set( "appId", "YOUR APP ID"); 
    			nokia.Settings.set( "authenticationToken", "YOUR TOKEN");
    //			
    /////////////////////////////////////////////////////////////////////////////////////
    	
    if(!Array.indexOf){
      Array.prototype.indexOf = function(obj){
       for(var i=0; i<this.length; i++){
        if(this[i]==obj){
         return i;
        }
       }
       return -1;
      }
    }
                
    function secondsToTime(secs)  {
        var hours = Math.floor(secs / (60 * 60));   
        var divisor_for_minutes = secs % (60 * 60);
        var minutes = Math.floor(divisor_for_minutes / 60);
        return "" + hours + ":" + minutes;
    }
    
    function zoomTolink(position){
    		var link = document.createElement("a");
    		link.onclick = function() {map.zoomTo(new nokia.maps.geo.BoundingBox(position));};
    		var img = document.createElement("img");
    		img.src = "http://api.maps.nokia.com/en/playground/examples/maps/res/kml/usgs/images/circle-blue.png";
    		link.appendChild (img);
    		return link;	
    }
    
    function calculateDistance(distance, metricMeasurements){
    		if (metricMeasurements){
    				if (distance < 1000){
    						return "" + maneuver.length + " m.";
    				} else {
    						return "" + Math.floor(distance/100)/10 + " km.";
    				}
    		} else {
    				if (distance < 1610){
    						return "" + Math.floor(distance/1.0936) + " yards";
    				} else {
    						return "" + Math.floor(distance/160.934)/10 + " miles";
    				}
    		}
    }
    
    function addBold(text){
    	var bold = document.createElement('strong');
    	bold.appendChild(document.createTextNode(text));
    	return bold;
    }
    
    function addText(text){
    	var node = document.createElement("span");
    	node.innerHTML = text;
    	return node;
    }
    
    function addMarker( manuever, text){
      
      var marker = new nokia.maps.map.Marker(
            manuever.position,{
            icon: "http://api.maps.nokia.com/en/playground/examples/maps/res/kml/usgs/images/circle-blue.png",
            anchor: new nokia.maps.util.Point(5, 5)
      });
      
      var div = document.createElement("div");
    	div.appendChild(addText(text));
    	div.appendChild(document.createElement("br"));
    		
      // We'r really like to add this as a DOM element, but the InfoBubble accepts HTML.
      marker.html =   div.innerHTML;
    
      marker.addListener("click" ,  function(evt) { 
          infoBubbles.addBubble(evt.target.html, evt.target.coordinate);  
      }, false);
      
      markerPoints.objects.add(marker);
    }
    
    var infoBubbles = new nokia.maps.map.component.InfoBubbles();
    var scaleBar = new nokia.maps.map.component.ScaleBar (); 
    var contextMenu = new nokia.maps.map.component.ContextMenu();
    
    var startPoint;
    var endPoint;
    var mapRoute;
    var nodeOL;
    // This will hold the blue blobs.
    var markerPoints = new nokia.maps.map.Container();
    
    var myHandler = function(contextMenuEvent, group) {
    	
    		group.addEntry(
    					"Directions from Here",
    						function(activationEvent) {
    							startPoint = map.pixelToGeo(contextMenuEvent.targetX, contextMenuEvent.targetY);
    							if (endPoint !== undefined){
    								calculateRouteFromKnownWaypoints();
    							}
    		});
    		group.addEntry(
    					"Directions to Here",
    						function(activationEvent) {
    							endPoint  = map.pixelToGeo(contextMenuEvent.targetX, contextMenuEvent.targetY);
    							if (startPoint !== undefined){
    								calculateRouteFromKnownWaypoints();
    							}
    		});
    
    }
    contextMenu.removeHandler(nokia.maps.routing.component.ContextMenuHandler);
    contextMenu.addHandler(myHandler);
    
    // Set up the map, and ensure we will be able to interact with info bubbles.
    var    map = new nokia.maps.map.Display(document.getElementById("map"), 
             {     "components": [ 
                new nokia.maps.map.component.ZoomBar(),                 
    						new nokia.maps.map.component.Behavior(),                 
    						new nokia.maps.map.component.TypeSelector(),
    						contextMenu],  
    			center: [52.51, 13.4], 
               "zoomLevel": 10 }); 
        map.addComponent( infoBubbles);     
        map.addComponent( scaleBar);   
        map.objects.add(markerPoints);
    
    var onRouteCalculated = function (observedRouter, key, value) {
      if (value == "finished") {
    	    var routes = observedRouter.getRoutes();
    	    var ticker = document.getElementById("ticker");
    	    var metricMeasurements = (scaleBar.showImperialUnits == false);
    	    
    	    //create the default map representation of a route
    	    if (mapRoute !== undefined){
      			
    	   		map.objects.remove(mapRoute);
    	   		markerPoints.objects.clear();
    	   		nodeOL.parentNode.removeChild(nodeOL);
      		}
    	   	mapRoute = new nokia.maps.routing.component.RouteResultSet(routes[0]).container;
    
    	    map.objects.add(mapRoute);                  
    	    var route = routes[0]; // Take the FIRST route give.
    	    
    	    //Zoom to the bounding box of the route
    	    ticker.innerHTML = "Displaying Route";
    	    map.zoomTo(mapRoute.getBoundingBox(), false, "default");
    	    ticker.innerHTML = "";
          ticker.appendChild(addBold( secondsToTime(route.summary.baseTime)));
          ticker.appendChild(addText("	  distance: ")); 
          ticker.appendChild(addBold( calculateDistance(route.summary.distance,
          		metricMeasurements)));
    	   
    	     nodeOL = document.createElement("ol");
    	   
    	    for (var i = 0;  i < route.legs.length; i++){
                for (var j = 0;  j < route.legs[i].maneuvers.length; j++){
                      var details =  document.createElement("li");
                      // Get the next maneuver.
                      maneuver = route.legs[i].maneuvers[j];  
                      var instructions = maneuver.instruction; 
                       // For imperial measurements, extract the distance span
                     
                      if (metricMeasurements != true){
    	                   var ls = instructions.indexOf("<span class=\"length\">")
    	                   var ln = instructions.indexOf("</span>" , ls);	                  
    	                   if (ls > -1 && ln > -1){
    	               	   	  distNode = instructions.substring(ls + 21, ln);
    	               	   	  var n=distNode.split(" "); 	               	   	  
    	               	   	  if (n[1] == "meters"){	               	   	  		 
    	               	  	  		 imperialText = calculateDistance(n[0], false);
    	               	  	  } else {
    	               	  	  		 imperialText = calculateDistance(n[0] * 1000, false);
    	               	  	  }
    	               	  	   instructions = instructions.substring(0, ls + 21)
    	               	    	+  imperialText + instructions.substring(ln);
    	               	   }
    	               	  
                   	  }
                   	  
                      if (instructions.trim() != ""){                            
    		                  addMarker( maneuver, instructions);
    		                  details.appendChild (zoomTolink(maneuver.position));
    		                  details.appendChild (document.createTextNode(' '));                 
    		                  details.appendChild (addText(instructions));
    		                  nodeOL.appendChild(details);
                  	  }
                }
                
    	    }
    	    
    
    	    startPoint = undefined;
    		endPoint = undefined;
    	    // Display the list of manuevers on screen.
    	    document.getElementById("details").appendChild(nodeOL);
      
      } else if (value == "failed") {
          alert("The routing request failed.");
      }
    };
     
    var router = new nokia.maps.routing.Manager(); 
    router.addObserver("state", onRouteCalculated);
    
    
    var calculateRouteFromKnownWaypoints = function() {
        
      	
    		var waypoints = new nokia.maps.routing.WaypointParameterList();
    		waypoints.addCoordinate(startPoint);
    		waypoints.addCoordinate(endPoint);
    		
    		  var modes = [{ 
    		                  type: "shortest", 
    		                  transportModes: ["car"],
    		                  options: "",
    		                  trafficMode: "default"
    		                  }];
    		  document.getElementById("ticker").innerHTML = "Calculating Route";                                             
    		  router.calculateRoute(waypoints, modes);                                   
    };
    
    
    }());
    
    /*]]>*/         
    </script>
    </body>
    </html>

  4. #4
    Nokia Developer Expert
    Join Date
    Jul 2013
    Posts
    4

    Re: Routing result box

    Hi Jason,

    Thanks for your answer, but what i mean is like this link http://api.maps.ovi.com/playground2/...ompleterouting

    but the scripts is for Ovi maps, how to convert the Ovi maps script to Nokia map Script? is it same script?

    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
     <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>Complete routing example example</title>
    <script src="http://api.maps.ovi.com/jsl.js" type="text/javascript" charset="utf-8"></script>
    </head>
    <body>
    <div id="map1" style="z-index: -1;width: 60%;height: 78%;position: absolute;left: 320px;top: 70px;"></div>
    <div id="map2" style="z-index: -1;width: 310px;height: 100%;position: absolute;left: 3px;top: 3px;"></div>
    <div id="map3" style="z-index: -1;width: 80%;height: 61px;position: absolute;left: 320px;top: 3px;"></div>
    <div style="right: 20px; width: 240px; height: auto; position: absolute; background: none repeat scroll 0 0 #FFFFFF;">
    <h1>Complete routing example</h1><p>This example shows how different routing components can interact with eachother, e. g. waypoint input fields, right click menu and maneuver listing.</p><p>To create an example route, click the button below. You can also create your own route from by using right click menu or waypoint input fields.</p><input id="_b_route" type="button" value="Add example route"/><br /><p><span class="tip">Play around by modifying or adding to the code in the [[code area]].</span></p>
    </div>
    <script type="text/javascript">
    
    // Set the authentication token, which is needed by the web-services to authenticate your application.
    ovi.mapsapi.util.ApplicationContext.set("authenticationToken", "<Token>");
    
    var mapContainer1 = document.getElementById("map1");
    var mapContainer2 = document.getElementById("map2");
    var mapContainer3 = document.getElementById("map3");
    
    // create a map with default components inside the map container
    var map = (window.map = new ovi.mapsapi.map.Display(mapContainer1, {
    	center: [52.5, 13.4], zoomLevel: 10,
    	components: [ new ovi.mapsapi.map.component.Behavior(),
    				  new ovi.mapsapi.map.component.RightClick()
    				]
    }));
    
    // create needed managers for route calculation and search
    var router = new ovi.mapsapi.routing.Manager()
    var searcher = new ovi.mapsapi.search.Manager()
    
    // create needed components and ensure that all of them use the same managers
    var routeComponent	 = new ovi.mapsapi.routing.component.RouteComponent(router, searcher);
    var routeRCComponent   = new ovi.mapsapi.routing.component.RightClick(router, routeComponent);
    var searchRCComponent	= new ovi.mapsapi.search.component.RightClick(searcher);
    var waypointsComponent = new ovi.mapsapi.routing.component.Waypoints(mapContainer3, router, searcher);
    var routeViewComponent = new ovi.mapsapi.routing.component.RouteView(mapContainer2, router);
    
    // attach components to map
    routeRCComponent = map.addComponent(routeRCComponent);
    searchRCComponent = map.addComponent(searchRCComponent);
    waypointsComponent = map.addComponent(waypointsComponent);
    routeViewComponent = map.addComponent(routeViewComponent);
    routeComponent = map.addComponent(routeComponent);
    
    routeViewComponent.useRouteComponent(routeComponent);
    
    // create an example route
    var newroute = document.getElementById("_b_route");
    newroute.onclick = function(){
    	routeComponent.clear();
    	routeComponent.setStart( new ovi.mapsapi.geo.Coordinate(50.1120423728813, 8.68340740740811));
    	routeComponent.setDestination( new ovi.mapsapi.geo.Coordinate(50.140411376953125, 8.572110176086426));
    
    	var modes = [{
    		type: "shortest",
    		transportModes: ["car"],
    		options: "avoidTollroad",
    		trafficMode: "default"
    	}];
    
    	// init route calculation (route drawing, maneuver listing etc. is handled by observer functions of corresponding components)
    	routeComponent.calculateRoute(modes);
    };
    
    </script>
    </body>
    </html>
    Last edited by jasfox; 2013-07-22 at 09:18.

  5. #5
    Regular Contributor
    Join Date
    Aug 2011
    Location
    Berlin
    Posts
    289

    Re: Routing result box

    The upgrade path from OVI maps to the latest version of the HERE Maps API for JavaScript is discussed in a wiki article here. HERE Maps is the current brand name for the same product - effectively OVI was 1.0 and for most upgrades all you need to do is change the namespaces.

    That being said, there are some components which have either been removed or altered over time. The concept of an all-in one "geocode-two-complete-addresses-get-a-route-between-them-and-display-routing-instructions" component has been broken down into its constituent parts, since if you think about it very few websites apart from here.com will have need of the use case - routing from one unknown location to another unknown location. It is much more likely that at least one of the locations will be known, either if it is your custom data, or because an geocoding request has occurred previously.

    The current way of doing what you propose is as follows:

    • Add a SearchBox widget to the map for the "from" location.
    • Add a second SearchBox widget to the map for the "to" location.
    • Add a map to the page and use the center of the map as a hint location for suggestions of an address.
    • Add a custom component such as the RoutingDirectionRenderer described in the preivous post and attach it to the map.
    • Add a routing.Manager and invoke it on a button click once you have two coordinates.
    • Within the onRouteCalculated() callback method invoke the RoutingDirectionRenderer as shown.


    I've updated the Advanced Routing examples to give an example of how to do this.
    The current philosophy of one component one job has a couple of advantages : only a partial address is required, and you are not forced a specified layout to your UI. You are free to style the Elements as you see fit.
    Last edited by jasfox; 2013-07-22 at 12:11.

Similar Threads

  1. Routing example
    By tomgiam in forum [Archived] MH5: Nokia Maps Framework for mobile HTML5
    Replies: 2
    Last Post: 2013-01-11, 01:25
  2. Audio Routing API for S60 5th
    By heuven in forum Symbian User Interface
    Replies: 6
    Last Post: 2009-02-14, 23:39
  3. Routing
    By aidj in forum General Messaging
    Replies: 1
    Last Post: 2002-11-12, 06:01

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×