Fork me on GitHub

Leaflet Routing Machine

Easy, flexible routing for Leaflet

« Back to tutorials

Addresses and geocoders

Routing and addresses are tightly coupled. Perhaps the most common use case for routing if to get from address A to address B, where the user does not necessarily know the geographic location of those addresses. Since the routing software can only route between locations, latitudes and longitudes, the software needs a way to look up the coordinate of an address. This process is known as geocoding, looking up the latitude and longitude from an address string.

Likewise, it is common to put a waypoint on the map, and let the system look up the address of the waypoint. This is known as reverse geocoding, mapping a geographic location to an address string.

Although crucial to routing, Leaflet Routing Machine does not come with a builtin geocoder or reverse geocoder. There are quite a few geocoding services available, and instead of Leaflet Routing Machine choosing one for you, it lets you connect to the geocoding service of your choice. Luckily, adding geocoding is easy.

Adding a geocoding service

In Leaflet Routing Machine, geocoders work as a form of plugin. Geocoders must be written to conform with the interface used by Leaflet Control Geocoder (from the same author as Leaflet Routing Machine). This means that by simply including the file Control.Geocoder.js, it will be possible to use these geocoding services

Once you have a geocoding service loaded, you need to tell Leaflet Routing Machine to use it. This is done by adding the option geocoder to the control’s options, specifying the geocoder instance to use:

L.Routing.control({
    waypoints: [
        L.latLng(57.74, 11.94),
        L.latLng(57.6792, 11.949)
    ],
    routeWhileDragging: true,
    geocoder: L.Control.Geocoder.nominatim()
}).addTo(map);

See Leaflet Control Geocoder’s API for more information about the classes used, and their options.

Adding a geocoder will change the way the control works in two major ways:

1) Input fields for the waypoints’ addresses will be added to the control’s panel 2) Moving a waypoint by dragging it in the map, for example, will automatically look up the address of the new location and update the address field

This is an example of what it looks like:

Autocomplete

Leaflet Routing Machine supports autocomplete (or type ahead, as it’s sometimes called), meaning it can try to suggest addresses as the user types in an address field. To use this feature, the underlying geocoder service must support it. Support is added by giving the geocoder a method called suggest, which takes the same arguments as the geocode method.

Note that the perhaps most commonly used geocoder, Nominatim, does not have autocomplete, since its usage policy explicitly forbids it.

Below is an example of autocomplete/type ahead, with Mapbox’s geocoding service (currently works best in the U.S.). Go ahead, select one of the addresses and start typing. When you pause for a bit, suggestions based on what you’ve typed so far will appear.

Unknown addresses

As mentioned above, a reverse geocoding will be made every time a waypoint’s location changes, to reflect its new address. But what happens if there is no address for the location? This typically happens the waypoint is placed outside inhabited areas, like in the woods, mountains or similar.

For these cases, Leaflet Routing Machine has a fallback that generates a waypoint name. By default, a representation of its latitude and longitude will be used, like “N38.1086, W122.1762”.

If you want to override this behaviour, you can provide the option waypointNameFallback, which is a function that given the waypoint L.LatLng should return a name. Here’s an example of how to replace the default with sexagesimal format of the location:

L.Routing.control({
    [...]
    waypointNameFallback: function(latLng) {
        function zeroPad(n) {
            n = Math.round(n);
            return n < 10 ? '0' + n : n;
        }
        function sexagesimal(p, pos, neg) {
            var n = Math.abs(p),
                degs = Math.floor(n),
                mins = (n - degs) * 60,
                secs = (mins - Math.floor(mins)) * 60,
                frac = Math.round((secs - Math.floor(secs)) * 100);
            return (n >= 0 ? pos : neg) + degs + '°' +
                zeroPad(mins) + '\'' +
                zeroPad(secs) + '.' + zeroPad(frac) + '"';
        }

        return sexagesimal(latLng.lat, 'N', 'S') + ' ' + sexagesimal(latLng.lng, 'E', 'W');
    }
})

Implementing your own geocoder

For some cases, you might want to use a geocoding service that is not supported by Leaflet Control Geocoder. This can be done easily by implementing the same interface (contract) that for your service. IGeocoder lists which methods you need to implement; optionally you might want to add suggest as well, as mentioned under the Autocomplete heading above.

Then simply pass your own geocoder instance to the geocoder option, just like the examples above.


Copyright © 2015 Per Liedman, released under ISC License. Logo by Alexey Ivanov, released under Creative Commons CC-BY 3.0.
×

Sorry! The OSRM demo server appears down, or a network error occured.

This prevents Leaflet Routing Machine from displaying a route. The demo server will hopefully be back up soon. Please do not report this as an issue, Leaflet Routing Machine has no control over the demo server.

In production, set up your own OSRM instance, or pay a service provider.