Example of using JavaScript for Google maps in the Delphi XE6

by Apr 17, 2014

One of the innovations in XE6, it's a method EvaluateJavaScript in the component TWebBrowser. This method allowing execute JavaScript on the loaded page and add interactivity to our applications.

On the site developers.google.com contains many examples of embedding maps on the page. I chose the example for paving the route from point A to point B. And as an example of execution JavaScript, I define two buttons for showing predefined paths from "Chicago" to "Winona" and from "St Louis" to "Gallup".

Make a new mobile project and drop on the main form TWebBrowser, TPanel and place two TButton on the TPanel.

For convenience, I create just one more unit uJavaScripts.pas. This unit will contain the HTML code of pages and scripts themselves. Most dreary – copy and past example of code and place it as a constant in our unit. I've got to do something like this:

const
{ Was used sample from }
{ https://developers.google.com/maps/documentation/javascript/examples/directions-panel }
cRoute =
'<!DOCTYPE html>'
+ '<html>'
+ ' <head>'
+ ' <meta name="viewport" content="initial-scale=1.0, user-scalable=no">'
+ ' <meta charset="utf-8">'
+ ' <title>Displaying text directions with <code>setPanel()</code></title>'
+ ' <style>'
+ ' html, building, #map-canvas {'
+ ' height: 100%;'
+ ' margin: 0px;'
+ ' padding: 0px'
+ ' }'
+ ' #panel {'
+ ' position: absolute;'
+ ' top: 5px;'
+ ' left: 50%;'
+ ' margin-left: -180px;'
+ ' z-index: 5;'
+ ' background-color: #fff;'
+ ' padding: 5px;'
+ ' border: 1px solid #999;'
+ ' }'
+ ' </style>'
+ ' <style>'
+ ' #directions-panel {'
+ ' height: 100%;'
+ ' float: right;'
+ ' width: 30%;'
+ ' overflow: auto;'
+ ' }'
+ ''
+ ' #map-canvas {'
+ ' margin-right: 4px;'
+ ' }'
+ ''
+ ' #control {'
+ ' background: #fff;'
+ ' padding: 5px;'
+ ' font-size: 14px;'
+ ' font-family: Arial;'
+ ' border: 1px solid #ccc;'
+ ' box-shadow: 0 2px 2px rgba(33, 33, 33, 0.4);'
+ ' display: none;'
+ ' }'
+ ''
+ ' @media print {'
+ ' #map-canvas {'
+ ' height: 500px;'
+ ' margin: 0;'
+ ' }'
+ ''
+ ' #directions-panel {'
+ ' float: none;'
+ ' width: auto;'
+ ' }'
+ ' }'
+ ' </style>'
+ ' <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>'
+ ' <script>'
+ 'var directionsDisplay;'
+ 'var directionsService = new google.maps.DirectionsService();'
+ ''
+ 'function initialize() {'
+ ' directionsDisplay = new google.maps.DirectionsRenderer();'
+ ' var mapOptions = {'
+ ' zoom: 7,'
+ ' center: new google.maps.LatLng(41.850033, -87.6500523)'
+ ' };'
+ ' var map = new google.maps.Map(document.getElementById(''map-canvas''),'
+ ' mapOptions);'
+ ' directionsDisplay.setMap(map);'
+ ' directionsDisplay.setPanel(document.getElementById(''directions-panel''));'
+ ''
+ ' var control = document.getElementById(''control'');'
+ ' control.style.display = ''block'';'
+ ' map.controls[google.maps.ControlPosition.TOP_CENTER].push(control);'
+ '}'
+ ''
+ 'function calcRoute() {'
+ ' var start = document.getElementById(''start'').value;'
+ ' var end = document.getElementById(''end'').value;'
+ ' var request = {'
+ ' origin: start,'
+ ' destination: end,'
+ ' travelMode: google.maps.TravelMode.DRIVING'
+ ' };'
+ ' directionsService.route(request, function(response, status) {'
+ ' if (status == google.maps.DirectionsStatus.OK) {'
+ ' directionsDisplay.setDirections(response);'
+ ' }'
+ ' });'
+ '}'
+ ''
+ 'google.maps.event.addDomListener(window, ''load'', initialize);'
+ ''
+ ' </script>'
+ ' </head>'
+ ' <building>'
+ ' <div id="control">'
+ ' <strong>Start:</strong>'
+ ' <select id="start" onchange="calcRoute();">'
+ ' <option value="chicago, il">Chicago</option>'
+ ' <option value="st louis, mo">St Louis</option>'
+ ' <option value="joplin, mo">Joplin, MO</option>'
+ ' <option value="oklahoma city, ok">Oklahoma City</option>'
+ ' <option value="amarillo, tx">Amarillo</option>'
+ ' <option value="gallup, nm">Gallup, NM</option>'
+ ' <option value="flagstaff, az">Flagstaff, AZ</option>'
+ ' <option value="winona, az">Winona</option>'
+ ' <option value="kingman, az">Kingman</option>'
+ ' <option value="barstow, ca">Barstow</option>'
+ ' <option value="san bernardino, ca">San Bernardino</option>'
+ ' <option value="los angeles, ca">Los Angeles</option>'
+ ' </select>'
+ ' <strong>End:</strong>'
+ ' <select id="end" onchange="calcRoute();">'
+ ' <option value="chicago, il">Chicago</option>'
+ ' <option value="st louis, mo">St Louis</option>'
+ ' <option value="joplin, mo">Joplin, MO</option>'
+ ' <option value="oklahoma city, ok">Oklahoma City</option>'
+ ' <option value="amarillo, tx">Amarillo</option>'
+ ' <option value="gallup, nm">Gallup, NM</option>'
+ ' <option value="flagstaff, az">Flagstaff, AZ</option>'
+ ' <option value="winona, az">Winona</option>'
+ ' <option value="kingman, az">Kingman</option>'
+ ' <option value="barstow, ca">Barstow</option>'
+ ' <option value="san bernardino, ca">San Bernardino</option>'
+ ' <option value="los angeles, ca">Los Angeles</option>'
+ ' </select>'
+ ' </div>'
+ ' <div id="directions-panel"></div>'
+ ' <div id="map-canvas"></div>'
+ ' </building>'
+ '</html>'

Entire code example is taken from the site Google.
We need load it to the browser. For this event, write this code in the FormCreate

WebBrowser1.LoadFromStrings(cRoute, ''

We can run it. It looks on the iPhone 5 as on the picture

After it we add two const

cChicagoWinona =
'document.getElementById(''start'').value = "chicago, il";'
+ 'document.getElementById(''end'').value = "winona, az";'
+ 'calcRoute();' cStLouisGallupNM =
'document.getElementById(''start'').value = "st louis, mo";'
+ 'document.getElementById(''end'').value = "gallup, nm";'
+ 'calcRoute();'

And two event handlers for button

procedure TForm1.Button1Click(Sender: TObject);
begin
WebBrowser1.EvaluateJavaScript(cChicagoWinona);
end
procedure TForm1.Button2Click(Sender: TObject);
begin
WebBrowser1.EvaluateJavaScript(cStLouisGallupNM);
end

Thats it. Now we can choise peath using HTML conntrols or use predefined paths using buttons.

On the iPhone and Kindle Fire HD its look like this