Copyright Derek O'Reilly, Dundalk Institute of Technology (DkIT), Dundalk, Co. Louth, Ireland.
Google provide a JavaScript API that can be used to place Google maps into a webpage. You need to have a GoogleMap API key in order to use Google Maps. Go to https://console.cloud.google.com/ to open the Google Maps "Dashboard", as highlighted below.
Within the DASHBOARD screen, select the "APIs & Services" menu option and then select the "Credentials" menu option, as highlighted below.
Within the Credentials screen, select the "API key" menu item from the "CREATE CREDENTIALS" menu to create a new key, as highlighted below.
Your API keys will be listed on the Credentials screen, as highlighted below.
Select the "Library" option from the "APIs & Services" menu, as highlighed below.
Within the "API Library screen", we need to enable each of the libraries that we intend to use with our Google Maps key. Enable the JavaScript, Places, Roads, and Directions libraries, as highlighted below.
Excellent Google Maps documentation can be found at https://developers.google.com/maps/documentation/javascript/.
Example of a GoogleMap (Run Example)
<!DOCTYPE html> <html> <head> <title>Course notes example code</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> #map { width:600px; height:600px; border:thin solid #ccc; } </style> <script> function loadMap() { // These constants must start at 0 // These constants must match the data layout in the 'locations' array below const CONTENT = 0, LATITUDE = 1, LONGITUDE = 2 let locations = [ ["DkIT", 53.98485693, -6.39410164], ["Dundalk", 54.00428271, -6.40210535], ["Blackrock", 53.96251869, -6.36627104] ] let map = new google.maps.Map(document.getElementById("map"), { mapId: "MY_MAP_ID", zoom: 12, center: new google.maps.LatLng(locations[0][LATITUDE], locations[0][LONGITUDE]), mapTypeId: google.maps.MapTypeId.ROADMAP }) let infoWindow = null locations.forEach(location => { let marker = new google.maps.marker.AdvancedMarkerElement({ position: new google.maps.LatLng(location[LATITUDE], location[LONGITUDE]), map: map }) if(infoWindow === null) { infoWindow = new google.maps.InfoWindow() } google.maps.event.addListener(marker, "click", () => { infoWindow.setContent(location[CONTENT]) infoWindow.open(map, marker) }) }) } </script> </head> <body> <div id=map></div> <!-- Google Maps --> <script src=https://maps.googleapis.com/maps/api/js?key=AIzaSyB_9Q43Ef1CpjraTexylGFtj_tZNDYhbn4&loading=async&callback=loadMap&libraries=marker></script> </body> </html>
To use the Google Maps API on your webpage, you need to include the following code. You need to use your own Google Maps key.
<!-- Google Maps --> <script src=https://maps.googleapis.com/maps/api/js?key=INSERT_YOUR_KEY_HERE&loading=async&callback=loadMap></script>
The loadMap function will be called asynchronously (as soon as the Google Maps library has loaded). Once the Google library has loaded, the loadMap() function will be called.
Your map can hold any number of markers. If using several markers, then the markers' names, latitudes and longtitudes can be stored in an array. The constant values CONTENT, LATITUDE and LONGITUDE are used to identify positions within the locations array. For example, CONTENT refers to element 0 for each location within the locations array
// These constants must start at 0 // These constants must match the data layout in the 'locations' array below let CONTENT = 0, LATITUDE = 1, LONGITUDE = 2 let locations = [ ["DkIT", 53.98485693, -6.39410164], ["Dundalk", 54.00428271, -6.40210535], ["Blackrock", 53.96251869, -6.36627104] ]
A map is used to step through each marker, as shown below:
locations.forEach(location => { ... })
The <DIV> element that will hold the map, the mapId, the initial centre of the map, the zoom value of the map and the map type (road, satellite, hybrid, et cetera) are set using the code below:
let map = new google.maps.Map(document.getElementById("map"), { mapId:: "MY_MAP_ID", zoom: 12, center: new google.maps.LatLng(locations[0][LATITUDE], locations[0][LONGITUDE]), mapTypeId: google.maps.MapTypeId.ROADMAP })
An infoWindow is used to hold the content that is displayed when a user clicks on a marker. An event listerner is associated with each marker, so that the infoWindow displays the marker's content when the marker is clicked.
let infoWindow = new google.maps.InfoWindow() locations.forEach(location => { let marker = new google.maps.marker.AdvancedMarkerElement({ position: new google.maps.LatLng(location[LATITUDE], location[LONGITUDE]), map: map }) google.maps.event.addListener(marker, "click", () => { infoWindow.setContent(location[CONTENT]) infoWindow.open(map, marker) }) })
We can use a Google Maps Latitude and Longtitude finder below to get the values for the map markers.
http://gps.ie/gps-lat-long-finder.htm
Write code to show the location of your own home city. Scale the map, so that it includes your entire country, as shown here.
google.maps.marker.AdvancedMarkerElement can allow markers to animate. Write code to animate the marker for your hometown, as shown here.
Write code to show text when a user hovers over a marker, as shown here.
google.maps.marker.AdvancedMarkerElement can be changed to used different icons. Write code to place a symbol over various parking places in your own town, as shown here.
A marker's content can be any HTML. To create a custom marker, we replace the text content with HTML in the previous example, as shown below.
Example of a Custom Content GoogleMap (Run Example)
<!DOCTYPE html> <html> <head> <title>Course notes example code</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> #map { width:600px; height:600px; border:thin solid #ccc; } #dkit-content { width:400px; height:200px; } #dkit-content img { clear:both; float:left; width: 150px; border-radius:100px; margin: 20px; margin-top:0px; border:thin solid #CCC; } </style> <script> function loadMap() { // These constants must start at 0 // These constants must match the data layout in the 'locations' array below const CONTENT = 0, LATITUDE = 1, LONGITUDE = 2 let dkitContent = `<div id=dkit-content> <h1>Dundalk Institute of Technology</h1> <div id=content> <img src = images/dkit_photo.png> <p>Dundalk Institute of Technology is the best place to study computing in Ireland </p> <p>For more information, see our website<br><a href=https://www.dkit.ie>www.dkit.ie</a></p> </div> </div>` let locations = [ [dkitContent, 53.98485693, -6.39410164], ["Dundalk", 54.00428271, -6.40210535], ["Blackrock", 53.96251869, -6.36627104] ] let map = new google.maps.Map(document.getElementById("map"), { mapId: "MY_MAP_ID", zoom: 12, center: new google.maps.LatLng(locations[0][LATITUDE], locations[0][LONGITUDE]), mapTypeId: google.maps.MapTypeId.ROADMAP }) let infoWindow = null locations.forEach(location => { let marker = new google.maps.marker.AdvancedMarkerElement({ position: new google.maps.LatLng(location[LATITUDE], location[LONGITUDE]), map: map }) if(infoWindow === null) { infoWindow = new google.maps.InfoWindow() } google.maps.event.addListener(marker, "click", () => { infoWindow.setContent(location[CONTENT]) infoWindow.open(map, marker) }) }) } </script> </head> <body> <div id=map></div> <p>Click on the DkIT place-marker to see an example of a custom place-marker.</p> <!-- Google Maps --> <script src=https://maps.googleapis.com/maps/api/js?key=AIzaSyB_9Q43Ef1CpjraTexylGFtj_tZNDYhbn4&loading=async&callback=loadMap&libraries=marker></script> </body> </html>
The marker's HTML content is placed into a string called dkitContent.
let dkitContent = `<div id=dkit-content>
<h1>Dundalk Institute of Technology</h1>
<div id=content>
<img src = images/dkit_photo.png>
<p>Dundalk Institute of Technology is the best place to study computing in Ireland.</p>
<p>For more information, see our website<br><a href=https://www.dkit.ie>www.dkit.ie</a></p>
</div>
</div>`
The style of the content can be set in the normal way using style sheets, as shown in the code below:
#dkit-content { width:400px; height:200px; } #dkit-content img { clear:both; float:left; width: 150px; border-radius:100px; margin: 20px; margin-top:0px; border:thin solid #CCC; }
Make your own cutom content for a marker. Do not copy the design from the example above.
Create custom content that displays a marker's content in a speech bubble, as shown here. Hint: You need only change the CSS.
Amend the example above to dynamically load the marker details from a JSON file, as shown here.
By default, Google Maps shows points of interest along with any markers that the user adds to a map. Using the code below, we can hide the points of interest on a map.
Example hiding points of interest on a map (Run Example)
<!DOCTYPE html> <html> <head> <title>Course notes example code</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> #map { width:600px; height:600px; border:thin solid #ccc; } </style> <script> function loadMap() { let dkitLocation = {lat:53.98485693, lng:-6.39410164} let map = new google.maps.Map(document.getElementById("map"), { mapId: "MY_MAP_ID", zoom: 16, center: dkitLocation, mapTypeId: google.maps.MapTypeId.ROADMAP, mapTypeControlOptions: { mapTypeIds: ["roadmap", "satellite", "hide_poi"] } }) hidePointsOfInterest(map) let infoWindow = null let marker = new google.maps.marker.AdvancedMarkerElement({ position: dkitLocation, map: map }) if(infoWindow === null) { infoWindow = new google.maps.InfoWindow() } google.maps.event.addListener(marker, "click", () => { infoWindow.setContent("DkIT") infoWindow.open(map, marker) }) } function hidePointsOfInterest(map) { let styles = [ { "featureType": "poi", "stylers": [{"visibility": "off"}] } ] let styledMapType = new google.maps.StyledMapType(styles, {name: "POI Hidden", alt: "Hide Points of Interest"}) map.mapTypes.set("hide_poi", styledMapType) map.setMapTypeId("hide_poi") } </script> </head> <body> <div id=map></div> <p>Use the "Map", "Satellite" and "Hide POI" buttons to show or hide points of interest on the map.</p> <!-- Google Maps --> <script src=https://maps.googleapis.com/maps/api/js?key=AIzaSyB_9Q43Ef1CpjraTexylGFtj_tZNDYhbn4&loading=async&callback=loadMap&libraries=marker></script> </body> </html>
The mapTypeControlOptions property holds the list of the map types that can be viewed for a given map. In the code below, "roadmap" and "satellite" are system-defined map types, and "hide_poi" is a user-defined map type.
let map = new google.maps.Map(document.getElementById("map"), {
mapId: "MY_MAP_ID",
zoom: 16,
center: dkitLocation,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControlOptions: {
mapTypeIds: ["roadmap", "satellite", "hide_poi"]
}
})
The hidePointsOfInterest() method is a user-defined function that will hide the points of interest.
function hidePointsOfInterest(map)
The value styles is an array of JSON objects that can be used to specify the look-and-feel of various map features. In the code below, styles specifies that points of interest will not be visible.
The styles are applied to a styledMapType, which is then associated with a mapType called "hide_poi".
Finally, the setMapTypeId("hide_poi") method sets the map to use the "hide_poi" map type.
function hidePointsOfInterest(map) { let styles = [ { "featureType": "poi", "stylers": [{"visibility": "off"}] } ] let styledMapType = new google.maps.StyledMapType(styles, {name: "POI Hidden", alt: "Hide Points of Interest"}) map.mapTypes.set("hide_poi", styledMapType) map.setMapTypeId("hide_poi") }
The above example shows bus stops. Amend the above code so that Points of Interest and bus stops are hidden, as shown here.
Amend the code above, so that country and county borders are coloured red, as shown here.
Write code to only show the parking places near where you live. When the map initially displays, it should hide the points of interest. The user should be allowed to switch between hidden Points of Interest, road map and hybrid map, as shown here.
Change the code from the example above, so that the user is not allowed to choose which type of map they want to see. Instead, they can only see the map with hidden Points of Interest and hidden bus stops, as shown here.
By default, Google Maps shows a list of nearby services, such as hotels, cafes and banks. Using the services API, it is possible to search for specific types of place or individual places. In order to use the services API, we need to add &libraries=places along with our key when including the script for Google Maps API.
<!-- Google Maps -->
<script src="https://maps.googleapis.com/maps/api/js?key=INSERT_YOUR_KEY_HERE&loading=async&callback=loadMap&libraries=marker,places"></script>
We can filter the nearby services to only include specific services, such as cafes.
Example showing nearby cafes (Run Example)
<!DOCTYPE html> <html> <head> <meta charset=UTF-8> <meta name=viewport content="width=device-width, initial-scale=1.0"> <title>Google Maps local services example</title> <style> #map { width:600px; height:600px; border:thin solid #ccc; } </style> <script> let map = null function loadMap() { let services_centre_location = {lat: 54.00428271, lng: -6.40210535} // Dundalk map = new google.maps.Map(document.getElementById("map"), { mapId: "MY_MAP_ID", zoom: 17, center: new google.maps.LatLng(services_centre_location), mapTypeId: google.maps.MapTypeId.ROADMAP, mapTypeControlOptions: { mapTypeIds: ["roadmap", "hide_poi"] } }) hidePointsOfInterest(map) let service = new google.maps.places.PlacesService(map) service.nearbySearch({ location: services_centre_location, // centre of the search radius: 500, // radius (in metres) of the search type: "cafe" }, getNearbyServicesMarkers) } function getNearbyServicesMarkers(results, status) { if (status === google.maps.places.PlacesServiceStatus.OK) { results.forEach(result => { createMarker(result) }) } } let infoWindow function createMarker(place) { let icon = document.createElement("img") icon.src = place.icon icon.style.width = "20px" icon.style.height = "20px" let marker = new google.maps.marker.AdvancedMarkerElement({ map: map, cotent: icon, position: place.geometry.location }) infoWindow = new google.maps.InfoWindow() google.maps.event.addListener(marker, "click", () => { infoWindow.setContent(place.name) infoWindow.open(map, marker) }) } function hidePointsOfInterest(map) { let styles = [ { "featureType": "poi", "stylers": [{"visibility": "off"}] } ] let styledMapType = new google.maps.StyledMapType(styles, {name: "POI Hidden", alt: "Hide Points of Interest"}) map.mapTypes.set("hide_poi", styledMapType) map.setMapTypeId("hide_poi") } </script> </head> <body> <div id=map></div> <p>Show all cafes in Dundalk</p> <p>If you click on a marker, it will show the name of the business. It will not show any other details of the business.</p> <!-- Google Maps --> <script src=https://maps.googleapis.com/maps/api/js?key=INSERT_YOUR_KEY_HERE&loading=async&callback=loadMap&libraries=marker,places></script> </body> </html>
The nearbySearch() method is determined by a set of PlaceSearchRequest properties (in this example: location, radius and type). In this example, the search will prioritise cafes that are within a 500m radius of location.
The full set of PlaceSearchRequest properties are available at https://developers.google.com/maps/documentation/javascript/reference/places-service#PlaceSearchRequest
let service = new google.maps.places.PlacesService(map) service.nearbySearch({ location: services_centre_location, // centre of the search radius: 500, // radius (in metres) of the search type: "cafe" }, getNearbyServicesMarkers)
The results of the search are passed to the getNearbyServicesMarkers() function. In the code below, the results are used to create markers.
function getNearbyServicesMarkers(results, status) { if (status === google.maps.places.PlacesServiceStatus.OK) { results.forEach(result => { createMarker(result) }) } }
The code above uses service.nearbySearch() to select the places that will be displayed on the map. We can use service.textSearch() instead of using service.nearbySearch(), as shown here. Write code to do this. Compare the results of using service.nearbySearch() and service.textSearch().
Investigate online to find out when we should we use service.nearbySearch() and when should be use service.textSearch().
The code above searches against type:"cafe" to select the places that will be displayed on the map. We can search by keyword instead of type as shown here. Write code to do this. Compare the results of searching by type and keyword.
We can use the findPlaceFromQuery() method to search by name for a particular place, as shown here. Write code to do this.
We can use the findPlaceFromPhoneNumber() method to search by phone number for a particular place, as shown here. Write code to do this.
In the code above, Google Maps provides a default icon for the "cafe" marker. It is possible to use any image as a marker. Change the example code above so that it uses an image file as the "cafe" marker, as shown here.
In the code above, Google Maps provides a default icon for the "cafe" marker. It is possible to use Base64 to embed a marker's image inside the code. Change the example code above so that it uses a Base64 image as the "cafe" marker, as shown here.
Write code to only show the schools that are close by when the map is clicked, as shown here.
Amend the code from the previous question to allow the user to choose to display either cafes or schools, as shown here.
We can display the details of a Google Maps marker when the marker is clicked.
Example that displays some details of a clicked marker (Run Example)
<!DOCTYPE html> <html> <head> <meta charset=UTF-8> <meta name=viewport content="width=device-width, initial-scale=1.0"> <title>Google Maps local services details example</title> <style> #map { width:600px; height:600px; border:thin solid #ccc; } </style> <script> let service let map function loadMap() { let services_centre_location = {lat: 54.00428271, lng: -6.40210535} // Dundalk map = new google.maps.Map(document.getElementById("map"), { mapId: "MY_MAP_ID", zoom: 17, center: new google.maps.LatLng(services_centre_location), mapTypeId: google.maps.MapTypeId.ROADMAP, mapTypeControlOptions: { mapTypeIds: ["roadmap", "hide_poi"] } }) hidePointsOfInterest(map) service = new google.maps.places.PlacesService(map) service.nearbySearch({ location: services_centre_location, // centre of the search radius: 500, // radius (in metres) of the search type: "cafe" }, getNearbyServicesMarkers) } function getNearbyServicesMarkers(results, status) { if (status === google.maps.places.PlacesServiceStatus.OK) { results.forEach(result => { createMarker(result) }) } } let infoWindow function createMarker(place) { let icon = document.createElement("img") icon.src = place.icon icon.style.width = "20px" icon.style.height = "20px" let marker = new google.maps.marker.AdvancedMarkerElement({ map: map, content: icon, position: place.geometry.location }) infoWindow = new google.maps.InfoWindow() google.maps.event.addListener(marker, "click", () => { request = { placeId: place.place_id, fields: ["name", "formatted_address", "international_phone_number", "icon", "geometry"], }; service.getDetails(request, (placeDetails) => infoWindow.setContent(`<p><strong>${placeDetails.name}</strong><br>${placeDetails.formatted_address}</br>${placeDetails.international_phone_number}</p>`)) infoWindow.open(map, marker) }) } function hidePointsOfInterest(map) { let styles = [ { "featureType": "poi", "stylers": [{"visibility": "off"}] } ] let styledMapType = new google.maps.StyledMapType(styles, {name: "POI Hidden", alt: "Hide Points of Interest"}) map.mapTypes.set("hide_poi", styledMapType) map.setMapTypeId("hide_poi") } </script> </head> <body> <div id=map></div> <p>Show all cafes in Dundalk</p> <p>If you click on a marker, it will show the name (in bold), address and phone number of the business</p> <!-- Google Maps --> <script src=https://maps.googleapis.com/maps/api/js?key=INSERT_YOUR_KEY_HERE&loading=async&callback=loadMap&libraries=marker,places></script> </body> </html>
A marker is created for each result from the nearbySearch().
The default icon for a given place is held in place.icon
The result (i.e. place in the createMarker() method) contains limited details about a given place. The full set of details for a given place are available by calling the getDetails() method. We pass a query to getDetails() with placeId and fields properties. The fields property contains a list of the fields that we want returned in the search result (in our example, we return "name", "formatted_address", "international_phone_number", "icon", and "geometry").
function getNearbyServicesMarkers(results, status) { if (status === google.maps.places.PlacesServiceStatus.OK) { results.forEach(result => { createMarker(result) }) } } let infoWindow function createMarker(place) { let icon = document.createElement("img") icon.src = place.icon icon.style.width = "20px" icon.style.height = "20px" let marker = new google.maps.marker.AdvancedMarkerElement({ map: map, content: icon, position: place.geometry.location }) infoWindow = new google.maps.InfoWindow() google.maps.event.addListener(marker, "click", () => { request = { placeId: place.place_id, fields: ["name", "formatted_address", "international_phone_number", "icon", "geometry"], }; service.getDetails(request, (placeDetails) => infoWindow.setContent(`<p><strong>${placeDetails.name}</strong><br>${placeDetails.formatted_address}</br>${placeDetails.international_phone_number}</p>`)) infoWindow.open(map, marker) }) }
Why should you only return the fields that you need when you call getDetails().
Amend the above code, so that the address is separated over several lines and the phone number is formatted as a local phone number, as shown here.
Amend the above code, so that a photo is displayed between the name and address, as shown here. Remember to deal with the case where a place does not have a photo associated with it.
The Google Maps DirectionsService object can be used to calculate and display the route between two points. An example route planner is shown below.
Example of a Route Planner (Run Example)
<!DOCTYPE html> <html> <head> <meta charset=UTF-8> <meta name=viewport content="width=device-width, initial-scale=1.0"> <title>Google Maps Route Finder example</title> <style> #map { width:100%; height:600px; border:thin solid #CCC; } #control-panel { background-color: #fff; margin-bottom:50px; } .select-location-label { font-weight:bold; min-width:40px; display:inline-block; } </style> <script> let directionsRenderer = null function loadMap() { let map = new google.maps.Map(document.getElementById("map"), { mapId: "MY_MAP_ID", zoom: 10, mapTypeId: google.maps.MapTypeId.ROADMAP }) directionsRenderer = new google.maps.DirectionsRenderer() directionsRenderer.setMap(map) calculateRoute() } function calculateRoute() { let start = document.getElementById("start").value let end = document.getElementById("end").value let request = {origin: start, destination: end, travelMode: google.maps.TravelMode.DRIVING} directionsService = new google.maps.DirectionsService() directionsService.route(request, (route, status) => { if (status === google.maps.DirectionsStatus.OK) { directionsRenderer.setDirections(route) } }) } </script> </head> <body> <div id=control-panel> <span class=select-location-label>Start:</span> <select id=start onChange=calculateRoute()> <option value="Dundalk Institute of Technology Louth Ireland">DkIT</option> <option value="Dublin City University Collins Avenue Extension Whitehall Dublin 9">DCU</option> <option value="Maynooth University Ireland">Maynooth</option> <option value="Queens University Belfast">Queens</option> </select> <br> <span class=select-location-label>End:</span> <select id=end onChange=calculateRoute()> <option value="Dundalk Institute of Technology Louth Ireland">DkIT</option> <option value="Dublin City University Collins Avenue Extension Whitehall Dublin 9" selected>DCU</option> <option value="Maynooth University Ireland">Maynooth</option> <option value="Queens University Belfast">Queens</option> </select> </div> <div id=map></div> <!-- Google Maps --> <script src=https://maps.googleapis.com/maps/api/js?key=INSERT_YOUR_KEY_HERE&loading=async&callback=loadMap&libraries=marker></script> </body> </html>
As directionsRenderer is being used in two different functions, it needs to be made global to the webpage.
let directionsRenderer = null
The value directionsRenderer is a google.maps.DirectionsRenderer(). This will allow it to render a route on top of another map.
The code directionsRenderer.setMap(map) identifies the map that the directionsRenderer will be rendered on top of.
function loadMap() { let map = new google.maps.Map(document.getElementById("map"), { mapId: "MY_MAP_ID", zoom: 10, mapTypeId: google.maps.MapTypeId.ROADMAP }) directionsRenderer = new google.maps.DirectionsRenderer() directionsRenderer.setMap(map) calculateRoute() }
The start and end variables are taking from the HTML <SELECT> elements.
The request parameter that is passed into directionsService includes start and end.
directionsService uses start and end to calculate the route. The route is used to set the directions of directionsRenderer, which will be overlayed onto the map that was previously associated with routOverlay.
function calculateRoute() { let start = document.getElementById("start").value let end = document.getElementById("end").value let request = {origin: start, destination: end, travelMode: google.maps.TravelMode.DRIVING} directionsService = new google.maps.DirectionsService() directionsService.route(request, (route, status) => { if (status === google.maps.DirectionsStatus.OK) { directionsRenderer.setDirections(route) } }) }
Adjust the code above so that it includes the option of allowing the user select waypoints along the route, as shown here.
Adjust the code above so that the user can type in the start and end locations using the Google Maps API predictive place names, as shown here.
GoogleMaps API provides can provide text directions for a Route Planner. The code below will output a route's text directions into the div called directions.
directionsRenderer.setPanel(document.getElementById("directions"))
Example of a Route Planner with text directions (Run Example)
<!DOCTYPE html> <html> <head> <meta charset=UTF-8> <meta name=viewport content="width=device-width, initial-scale=1.0"> <title>Google Maps Route Finder example</title> <style> #map { width:100%; height:600px; border:thin solid #CCC; } #control-panel { background-color: #fff; margin-bottom:50px; } .select-location-label { font-weight:bold; min-width:40px; display:inline-block; } #directions { width:100%; margin:0px; margin-top:20px; margin-bottom:50px; } </style> <script> let directionsRenderer = null function loadMap() { let map = new google.maps.Map(document.getElementById("map"), { mapId: "MY_MAP_ID", zoom: 10, mapTypeId: google.maps.MapTypeId.ROADMAP }) directionsRenderer = new google.maps.DirectionsRenderer() directionsRenderer.setMap(map) directionsRenderer.setPanel(document.getElementById("directions")) calculateRoute() } function calculateRoute() { let start = document.getElementById("start").value let end = document.getElementById("end").value let request = {origin: start, destination: end, travelMode: google.maps.TravelMode.DRIVING} directionsService = new google.maps.DirectionsService() directionsService.route(request, (route, status) => { if (status === google.maps.DirectionsStatus.OK) { directionsRenderer.setDirections(route) } }) } </script> </head> <body> <div id=control-panel> <span class=select-location-label>Start:</span> <select id=start onChange=calculateRoute()> <option value="Dundalk Institute of Technology Louth Ireland">DkIT</option> <option value="Dublin City University Collins Avenue Extension Whitehall Dublin 9">DCU</option> <option value="Maynooth University Ireland">Maynooth</option> <option value="Queens University Belfast">Queens</option> </select> <br> <span class=select-location-label>End:</span> <select id=end onChange=calculateRoute()> <option value="Dundalk Institute of Technology Louth Ireland">DkIT</option> <option value="Dublin City University Collins Avenue Extension Whitehall Dublin 9" selected>DCU</option> <option value="Maynooth University Ireland">Maynooth</option> <option value="Queens University Belfast">Queens</option> </select> </div> <div id=directions></div> <div id=map></div> <!-- Google Maps --> <script src=https://maps.googleapis.com/maps/api/js?key=INSERT_YOUR_KEY_HERE&loading=async&callback=loadMap&libraries=marker></script> </body> </html>
Select the HTML element on the webpage where the route's text directions will be displayed. In this example, it is the <DIV> element called directions.
// select the HTML element on the webpage where the route's text directions will be displayed directionsRenderer.setPanel(document.getElementById("directions"))
Adjust the above code, so that the user can press a button to select the type of transport that they will use for the journey, as shown here.
Adjust the above code, so that the directions can be minimised by the user, as shown here.
We can make a marker draggable by adding the property {draggable: true} to the DirectionsRenderer, as shown below.
directionsRenderer = new google.maps.DirectionsRenderer({draggable: true})
Dragging a marker will fire the "directions_changed" event. We can capture this using the code below. Note: In order to use the Geocoder in the code below, you must first enable the Geocoder library from the Google Cloud dashboard.
directionsRenderer.addListener("directions_changed", () => { const directions = directionsRenderer.getDirections() const geocoder = new google.maps.Geocoder() // update start address let start = directions.geocoded_waypoints[0].place_id geocoder.geocode({placeId: start}, (results, status) => { // results[0].formatted_address contains the start address console.log(results[0].formatted_address) }) // update end address let end = directions.geocoded_waypoints[1].place_id geocoder.geocode({placeId: end}, (results, status) => { // results[0].formatted_address contains the end address console.log(results[0].formatted_address) }) })
directionsRenderer.getDirections() returns the directions as a JSON object.
This JSON contains an array of geocoded_waypoints
directions.geocoded_waypoints[0].place_id and directions.geocoded_waypoints[1].place_id contain the place_id of the start and end point of the journey.
We use geocoder.geocode to convert the place_id to a formatted address, which can then be used to update a HTML text input element.
Write code to adjust the start or end address when the user drags the start address or end address marker, as shown here.
Copyright Derek O' Reilly, Dundalk Institute of Technology (DkIT), Dundalk, Co. Louth, Ireland.