All tutorials
Displaying the what3words grid on a Bing Maps
The what3words API supports the ability to obtain a section of the 3m x 3m what3words grid in GeoJSON format, making it very simple to display on a map.
This tutorial will show you how to integrate the what3words grid onto Bing Maps. We also have tutorials demonstrating its use with Google Maps, Mapbox, and LeafletJS.
Before you begin developing your application, you need to create a developer account on the Bing Maps Account Center. A Bing Maps Developer Account allows you to create a Bing Maps Key to use in your map application. Getting a key is described in Getting a Bing Maps Key.
To load the JavaScript wrapper for the what3words API, use a script
tag like the one in the following example. Replace YOUR-API-KEY
with your what3words API key to get started.
Note: We prefer to use a fixed version for the Production version of your integrations. A specific version can also be specified within the script to ensure a predictable version of the component is loaded, for example@4.0.6
. A log of versions can be found here.
<script src="https://cdn.what3words.com/javascript-components@4.0.6/dist/what3words/what3words.js?key=YOUR_API_KEY"></script>
The URL contained in the script tag is the location of a JavaScript file that loads everything you need for using the JavaScript wrapper for the what3words API.
The key
parameter contains your application’s API key.
You will also need to add a reference to the map control script of the Bing Maps API. You specify the key
parameter that contains your Bing Maps API key as part of the map script URL. The map control can be loaded asynchronously by specifying a callback function in the script URL and by adding “async defer” to the script tag as follows:
<script type="text/javascript" src="https://www.bing.com/api/maps/mapcontrol?callback=initMap&key=[YOUR_BING_MAPS_KEY]" async defer></script>
In the body
of the page, add a DIV
element to the page to contain the map. The size of the map is defined by the height and width of the DIV element. The position of the map is set by using the “position”, “top”, and “left” properties. You can set these values either inline or by defining the values in a style class and then referencing that class. In this example, we’ll set the map to display full screen, as follows:
<div id="myMap" style="position: relative;"></div>
Next, within a new script
tag, you need to create a function that can be called when your application loads.
<script type="text/javascript"> function initMap(selector, opts = {}) { const { lat = 51.52086, lng = -0.195499, zoom = 19 } = opts; map = new Microsoft.Maps.Map(selector, { center: new Microsoft.Maps.Location(lat, lng), zoom, }); } </script>
If loading the map synchronously, you can trigger the initMap
function by adding it to the onload
event of the body tag. If you wish to load the map asynchronously please follow this tutorial.
<body onload="initMap('#myMap');"> var map = new Microsoft.Maps.Map('#myMap');
The what3words grid can be drawn on top of a Bing Map by calling the what3words Grid API to obtain the grid squares within the currently visible bounding box of the map.
Because only a segment of the grid section can be requested, we need to obtain a new grid section each time the map is panned or zoomed.
<script> var map, drawingManager, gridData = [], square, info; /** * Initialises the MS Bing map and attaches event handlers */ function initMap(selector, opts = {}) { const { lat = 51.52086, lng = -0.195499, zoom = 19 } = opts; map = new Microsoft.Maps.Map(selector, { center: new Microsoft.Maps.Location(lat, lng), zoom, }); Microsoft.Maps.Events.addHandler( map, 'viewchangeend', function (e) { drawGrid() }, ); Microsoft.Maps.Events.addHandler( map, 'mapresize', function (e) { drawGrid() }, ); Microsoft.Maps.Events.addHandler( map, 'click', function (e) { drawSquare(e.location.latitude, e.location.longitude) }, ); } function clearGrid() { gridData.forEach(d => { map.entities.remove(d); }); } /** * Draws the grid on the map */ function drawGrid() { const zoom = map.getZoom(); const bounds = map.getBounds() // Zoom level is high enough if (zoom > 17) { const n = bounds.getNorth(); const s = bounds.getSouth(); const e = bounds.getEast(); const w = bounds.getWest(); const ne = new Microsoft.Maps.Location(n, e); const sw = new Microsoft.Maps.Location(s, w); // Call the what3words Grid API to obtain the grid squares within the current visible bounding box what3words.api .gridSection({ southwest: { lat: sw.latitude, lng: sw.longitude }, northeast: { lat: ne.latitude, lng: ne.longitude }, }) .then(function (data) { clearGrid(); gridData = data.lines.map(line => { const polyline = new Microsoft.Maps.Polyline([ new Microsoft.Maps.Location(line.start.lat, line.start.lng), new Microsoft.Maps.Location(line.end.lat, line.end.lng), ], { strokeColor: new Microsoft.Maps.Color(0.2, 125, 125, 125), strokeThickness: 1, }); map.entities.push(polyline); return polyline; }); }); } else { clearGrid(); } } function drawSquare(lat, lng) { const language = 'en'; what3words.api .convertTo3wa({ lat, lng }, language) .then(data => { const { square: { southwest, northeast } } = data; if (square) map.entities.remove(square); if (info) info.setMap(null); square = new Microsoft.Maps.Polygon([ new Microsoft.Maps.Location(southwest.lat, southwest.lng), new Microsoft.Maps.Location(southwest.lat, northeast.lng), new Microsoft.Maps.Location(northeast.lat, northeast.lng), new Microsoft.Maps.Location(northeast.lat, southwest.lng), ], { fillColor: new Microsoft.Maps.Color(0.4, 125, 125, 125), strokeColor: new Microsoft.Maps.Color(0.8, 0, 0, 0), strokeThickness: 2, }); info = new Microsoft.Maps.Infobox( new Microsoft.Maps.Location(lat, lng), { title: data.words }, ); info.setMap(map); map.entities.push(square); }); } </script>