!--a11y-->
Implement
the Action Handler onActionShowRoute 
In the action handler onActionShowRoute, you implement the functions for calculating the route. These are:
...
1. Read Addresses from the Input Fields
2. Calculate the Geo Coordinates for the Start and Destination Addresses
3. Calculate the Route
4. Create Geo Objects
5. Define the Map Border
To calculate the geo coordinates of the start and destination addresses, you must first save the address input of the user as WDGeoCoderAddress(String number, String street, String city, String region, String code, String country):
...
1. Switch to the Implementation tab page and add the following imports:
import java.net.MalformedURLException; import java.net.URL; import java.sql.Time; import java.util.ArrayList; import java.util.Iterator; import java.util.List;
import com.sap.tc.webdynpro.clientserver.uielib.graphics.api.*; 2. import com.sap.tc.webdynpro.services.exceptions.WDException; |
3. Add the following source code to the method onActionShowRoute:
4. onActionShowRoute |
public void onActionShowRoute(com.sap.tc.webdynpro.progmodel.api.IWDCustomEvent wdEvent ) { //@@begin onActionShowRoute(ServerEvent)
// read the User Input from Context and Add it to the // WDGeoCoderAddress
//Start-Address WDGeoCoderAddress addressStart = new WDGeoCoderAddress( wdContext.currentStartAddressElement().getNumber(), wdContext.currentStartAddressElement().getStreet(), wdContext.currentStartAddressElement().getCity(), "", wdContext.currentStartAddressElement().getCode(), "DE" );
//End-Address WDGeoCoderAddress addressEnd = new WDGeoCoderAddress( wdContext.currentDestinationAddressElement().getNumber(), wdContext.currentDestinationAddressElement().getStreet(), wdContext.currentDestinationAddressElement().getCity(), "", wdContext.currentDestinationAddressElement().getCode(), "DE" ); //@@end 5. } |
6.
To calculate the geo coordinates for the addresses, use the interface IWDGeoCoder. This interface is generated by the WDGeoFactory. As a result, the IWDGeoCoder provides a list with WDGeoCoderResultAddress for each address. If the address entered is not unique, this list will be larger than one.
A WDGeoCoderResultAddress contains a WDGeoPosition, which encapsulates the geo coordinate for this address (longitude, latitude, altitude).
The addresses for which to calculate the geo coordinates are added to the GeoCoder using addAddress(). After all addresses have been added to the GeoCoder, use setIgsUrl() to set the connection to the IGS. Use the command execute() to connect to the IGS and to calculate the WDGeoCoderResultAddresses.
...
1. Below the source code you entered before, add the following coding:
onActionShowRoute |
public void onActionShowRoute(com.sap.tc.webdynpro.progmodel.api.IWDCustomEvent wdEvent ) { ... try { // Calculate the GeoCode to the Addresses IWDGeoCoder geoCoder = WDGeoFactory.createGeoCoder();
// add the addresses to the geoCoder ( the geocoordinates are // calculated)
geoCoder.addAddress("0", addressStart); geoCoder.addAddress("1", addressEnd);
geoCoder.setIgsUrl(new URL("<URL to IGS with GeoServices>")); geoCoder.execute();
// startPos: GeoCode for startAddress WDGeoCoderResultAddress sResult = (WDGeoCoderResultAddress) geoCoder.getResultAddresses("0").get(0); WDGeoPosition startPos = sResult.getGeoPosition();
// endPos: GeoCode for destinationAddress WDGeoCoderResultAddress eResult = (WDGeoCoderResultAddress) geoCoder.getResultAddresses("1").get(0); WDGeoPosition endPos = eResult.getGeoPosition();
// add GeoCodes to the Context (Addresses) wdContext.currentStartAddressElement().setGeoPos(startPos); wdContext.currentDestinationAddressElement().setGeoPos(endPos);
} catch (WDException e1) { //if the addresses couldn't be added to the geoCoder e1.printStackTrace(); } //@@end } |
Caution: In
method setIgsUrl(), you must
replace the <URL to IGS with GeoServices> by your IGS
URL.
You use the IWDGeoRouter to calculate a route. Use addStop(String id, String description, WDGeoPosition pos) to transfer the route stops, set the IGS URL (setIgsUrl) and use execute() to calculate the route.
As a result, you can query the route path (getRoutePath), the duration (getRouteDuration) and the distance (getRouteDistance).
...
1. To calculate the route, add the following source code in method onActionShowRoute in the previously created try block and create another catch block.
onActionShowRoute |
public void onActionShowRoute(com.sap.tc.webdynpro.progmodel.api.IWDCustomEvent wdEvent ) { ... try {
...
// create GeoRouter IWDGeoRouter geoRouter = (IWDGeoRouter) WDGeoFactory.createGeoRouter();
// set the IgsUrl; this URL is an SAP-internal example geoRouter.setIgsUrl(new URL("<URL to IGS with GeoServices>"));
//add the GeoPositions of the Start- and Endaddress (potential //a breakpoint) to the geoRouter geoRouter.addStop("0", "0", startPos); geoRouter.addStop("1", "1", endPos);
//start the route calculation: geoRouter.execute();
// routeList: List of GeoPositions of the route path List routeList = geoRouter.getRoutePath();
// get RouteInformation: Duration and Distance and put it into //the context long duration = (long) geoRouter.getRouteDuration();
// Duration in ms duration = duration * 1000; wdContext.currentRouteInformationElement().setDuration(new Time(duration) );
wdContext.currentRouteInformationElement().setDistance( geoRouter.getRouteDistance());
} catch (WDException e1) { //if the addresses couldn't be added to the geoCoder e1.printStackTrace(); } catch (MalformedURLException e) { //if the connection to the IGS couldn't be established e.printStackTrace(); } //@@end } |
Caution: In
method setIgsUrl(), you must
replace the <URL to IGS with GeoServices> by your IGS
URL.
To display
the route on the map as a line and the addresses as bullets or graphics, you
must create
geo objects and
store them in the previously created context attribute geoObject.
...
1. To create the geo objects, add the following source code in method onActionShowRoute in the try block:
onActionShowRoute |
public void onActionShowRoute(com.sap.tc.webdynpro.progmodel.api.IWDCustomEvent wdEvent ) { ...
try { ...
//Add GeoObjects to the context----------------------------------- IPrivateGeoServiceView.IGeoDataNode geoDataNode = wdContext.nodeGeoData(); IPrivateGeoServiceView.IGeoDataElement geoDataElement;
// GeoLine: (Route) IWDGeoLine line = WDGeoFactory.createGeoLine("route"); line.setPositions( routeList ); line.setColor(java.awt.Color.blue); line.setWidth(5); geoDataElement = wdContext.createGeoDataElement(); geoDataElement.setGeoObject(line); geoDataNode.addElement(geoDataElement);
//Start Point IWDGeoPoint geoStartPoint = WDGeoFactory.createGeoPoint("0"); geoStartPoint.setTooltip("Start"); geoStartPoint.setPosition(startPos); geoStartPoint.setTriggersEvent(true); //id "5Y" of SAP-Icon (green flag) must be surrounded by @ geoStartPoint.setImage("@5Y@"); geoStartPoint.setLabel("Start"); geoDataElement = wdContext.createGeoDataElement(); geoDataElement.setGeoObject( geoStartPoint ); geoDataNode.addElement(geoDataElement);
//End Point IWDGeoPoint geoEndPoint = WDGeoFactory.createGeoPoint("1"); geoEndPoint.setTooltip("End"); geoEndPoint.setPosition(endPos); geoEndPoint.setTriggersEvent(true); geoEndPoint.setImage("@AV@"); geoEndPoint.setLabel("End"); geoDataElement = wdContext.createGeoDataElement(); geoDataElement.setGeoObject( geoEndPoint ); geoDataNode.addElement(geoDataElement);
//Add the geoPositions which should be displayed on the map in a //List List geoPositions = new ArrayList(); geoPositions.add(startPos); geoPositions.add(endPos);
//The the given method setMapBorder calculates the mapBorder with //a given distance from the nearest position to the border wdThis.setMapBorder(geoPositions, 0.1);
} catch (WDException e1) { //if the addresses couldn't be added to the geoCoder e1.printStackTrace(); } catch (MalformedURLException e) { //if the connection to the IGS couldn't be established e.printStackTrace(); }
//@@end } |
In the example, SAP icons are used for the start and destination addresses.
However, you can also display the destination as a bullet, a rectangle, and so
on.
To calculate the map border for the route, you can use the method setMapBorder(List geoPos, long distance), which already exists in the Web Dynpro project.
...
1. Add the following source code to the method:
setMapBorder |
public void setMapBorder( java.util.List wdGeoPositions, double distance ) { //@@begin setMapBorder() WDGeoPosition geoPosition; double lo, la, top, bottom, left, right;
Iterator it = wdGeoPositions.iterator(); geoPosition = (WDGeoPosition) it.next();
top = geoPosition.getLatitude(); bottom = geoPosition.getLatitude(); left = geoPosition.getLongitude(); right = geoPosition.getLongitude();
for(;it.hasNext();){ geoPosition = (WDGeoPosition) it.next(); la = geoPosition.getLatitude(); lo = geoPosition.getLongitude();
if(top > la) top = geoPosition.getLatitude(); if(bottom < la) bottom = la; if(left > lo) left = lo; if(right < lo) right = lo; }
//set Border Space to the geoPoints top = top - distance; bottom = bottom + distance; left = left - distance; right = right + distance;
WDGeoBorder mapBorder = new WDGeoBorder(left, top, right, bottom); wdContext.currentContextElement().setMapBorder(mapBorder); //@@end } |
2. Add the following source code to the action handler onActionShowRoute:
onActionShowRoute |
public void onActionShowRoute(com.sap.tc.webdynpro.progmodel.api.IWDCustomEvent wdEvent ) { ... try { ... //Add the geoPositions which should be displayed on the map in //a List List geoPositions = new ArrayList(); geoPositions.add(startPos); geoPositions.add(endPos);
//The the given method setMapBorder calculates the mapBorder // with a given distance from the nearest position to the //border wdThis.setMapBorder(geoPositions, 0.1);
} catch (WDException e1) { //if the addresses couldn't be added to the geoCoder e1.printStackTrace(); } catch (MalformedURLException e) { //if the connection to the IGS couldn't be established e.printStackTrace(); }
//@@end } |
Method wdDoModifyView is used to modify the view. If, after the route calculation, you want to display a different map sector, you use this method to set the borders differently.
3. In the wdDoModifyView method, add the following source code:
wdDoModifyView |
public static void wdDoModifyView(IPrivateGeoServiceView wdThis, IPrivateGeoServiceView.IContextNode wdContext, com.sap.tc.webdynpro.progmodel.api.IWDView view, boolean firstTime) { //@@begin wdDoModifyView
WDGeoBorder mapBorder; if(firstTime){ mapBorder= new WDGeoBorder(5.2, 55, 14.5, 47.3); wdContext.currentContextElement().setMapBorder(mapBorder); }
IWDGeoMap geomap = (IWDGeoMap) view.getElement("GeoMap"); mapBorder = wdContext.currentContextElement().getMapBorder(); geomap.setLeft(mapBorder.getLeft()); geomap.setRight(mapBorder.getRight()); geomap.setTop(mapBorder.getTop()); geomap.setBottom(mapBorder.getBottom()); //@@end } |
You have implemented the action handler onActionShowRoute in such a way that you can now calculate the route and display the new map borders using the geo objects.
Next
step:
