Maps and Routing
A full example with Leaflet
Now that we have gone through many different possibilities to embed different maps and features on our website, I will end the blog with a full example of what it could look like. We will use Leaflet and OSM to create a map that has auto-routing, and where you can add markers for the start, stop and waypoints by clicking on the map. I will show the code used and explain it. To start it off, we need an HTML-page with a few includes. The code looks like this:
<!DOCTYPE html>
<html>
<head>;
<meta charset="utf-8" />
<title>Leaflet OSRM Example</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet.js"></script>
</head>
<body>
<div id="map" style="height: 500px; width: 1000px"></div>
<script src="index.js"></script>
</body>
</html>
Just be sure to call the index.js after you created the div.
Afterwards, go on to modify the index.js.
Afterwards, go on to modify the index.js.
As mentioned in the last chapter, to create a basic map all you need is
var map = L.map('map');
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: 'Map data © &lt;a href="http://openstreetmap.org"&gt;OpenStreetMap&lt;/a&gt; contributors',
maxZoom: 18,
}).addTo(map);
Now we already have an OpenStreetMap, which by default is centered in London. But since we want to add more features, we have to add some new code. First of all, we want to include a so-called router, which does the auto-routing for us. Since this is no basic feature of Leaflet, we have to download the plugin first. I use the Leaflet routing machine plugin of Per Liedman, a solution free to use but still very good. If you want to learn more details about it, check out the website. Before we use the plugin, we have to import some files. Unfortunately, I coulnt find them online for a direct import, you will have to download them from the tutorial site and add them to your project. The files you need are leaflet-routing-machine.js, leaflet-routing-machine.css and leaflet.routing.icons.png. Be sure to add them to your HTML-file! Now we can go on and use the plugin in our index.js with the following code:
var map = L.map('map');
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: 'Map data © &lt;a href="http://openstreetmap.org"&gt;OpenStreetMap&lt;/a&gt; contributors',
maxZoom: 18
}).addTo(map);
This adds the auto-routing-machine, and also the starting point and end of our route. The points are from the example on Per Liedmans website, the map is now showing Göteborg, with two waypoints that are connected with the shortest route and a description of said route. Note that the way is shown for conventional cars, for other vehicles or for hikig and biking routes you need to modify the L.control object a little bit. The map also has two markers that can be dragged to set a new route, and the possibility to add more waypoints by dragging the route itself. One last thing we want to add is the possibility to click on the map to set the starting point and the end. We can do that with this code:map.on('click', function (e) {
var container = L.DomUtil.create('div'),
startBtn = button('Start from this location', container),
destBtn = button('End at this location', container);
L.DomEvent.on(startBtn, 'click', function () {
control.spliceWaypoints(0, 1, e.latlng);
map.removeLayer(startmarker);
startmarker = new L.marker(e.latlng, {draggable:'true'});
startmarker.on('dragend', function(event){
startmarker = event.target;
var position = startmarker.getLatLng();
control.spliceWaypoints(0, 1, position);
startmarker.setLatLng(new L.LatLng(position.lat, position.lng),{draggable:'true'});
});
map.addLayer(startmarker);
map.closePopup();
});
L.DomEvent.on(destBtn, 'click', function () {
control.spliceWaypoints(control.getWaypoints().length - 1, 1, e.latlng);
map.removeLayer(endmarker);
endmarker = new L.marker(e.latlng, {draggable:'true'});
endmarker.on('dragend', function(event){
endmarker = event.target;
var position = endmarker.getLatLng();
control.spliceWaypoints(control.getWaypoints().length - 1, 1, position);
endmarker.setLatLng(new L.LatLng(position.lat, position.lng),{draggable:'true'});
});
map.addLayer(endmarker);
map.closePopup();
});
L.popup().setContent(container).setLatLng(e.latlng).openOn(map);
});
Now, you can set the start and the end of your route by clicking on the map.
In the end, this is our full code:
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Leaflet OSRM Example</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" />
<link rel="stylesheet" href="leaflet-routing-machine.css"></script>
</head>
<body>
<div id="map" style="height: 500px; width: 1000px"></div>
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet.js"></script>
<script src="leaflet-routing-machine.js"></script>
<script src="index.js"></script>
</body>
</html>
index.js
function button(label, container) {
var btn = L.DomUtil.create('button', '', container);
btn.setAttribute('type', 'button');
btn.innerHTML = label;
return btn;
}
var map = L.map('map');
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors',
maxZoom: 18,
}).addTo(map);
var control = L.Routing.control({
waypoints: [
L.latLng(57.74, 11.94),
L.latLng(57.6792, 11.949)
],
routeWhileDragging: false
}).addTo(map);
var startBtn;
var destBtn;
var startmarker = new L.marker([44.91221, 7.671685], {draggable:'true'});
var endmarker = new L.marker([44.907852, 7.673789], {draggable:'true'});
map.on('click', function (e) {
var container = L.DomUtil.create('div'),
startBtn = button('Start from this location', container),
destBtn = button('End at this location', container);
L.DomEvent.on(startBtn, 'click', function () {
control.spliceWaypoints(0, 1, e.latlng);
map.removeLayer(startmarker);
startmarker = new L.marker(e.latlng, {draggable:'true'});
startmarker.on('dragend', function(event){
startmarker = event.target;
var position = startmarker.getLatLng();
control.spliceWaypoints(0, 1, position);
startmarker.setLatLng(new L.LatLng(position.lat, position.lng),{draggable:'true'});
});
map.addLayer(startmarker);
map.closePopup();
});
L.DomEvent.on(destBtn, 'click', function () {
control.spliceWaypoints(control.getWaypoints().length - 1, 1, e.latlng);
map.removeLayer(endmarker);
endmarker = new L.marker(e.latlng, {draggable:'true'});
endmarker.on('dragend', function(event){
endmarker = event.target;
var position = endmarker.getLatLng();
control.spliceWaypoints(control.getWaypoints().length - 1, 1, position);
endmarker.setLatLng(new L.LatLng(position.lat, position.lng),{draggable:'true'});
});
map.addLayer(endmarker);
map.closePopup();
});
L.popup().setContent(container).setLatLng(e.latlng).openOn(map);
});
L.Routing.errorControl(control).addTo(map);
Together
with the other files needed, you now have a map with OpenStreetMaps
layout, with the possibility to add start and endpoints and
waypoints in between, and a router that finds the best route all on its
own. Everything is open-source (be sure to check the terms anyways)
and free, but working really well. You can add countless other
features too, just as you need them, but to show them all would take
a lot of time, and there is already a good documentation for anything you might need. Still, I tried to give you an idea of what and how to use
the tools, and hope you learned a lot.
Hi. Nice tutotial. How can I set start point of the route from ecoordinates fro external php file(goejson output)?
ReplyDeleteThanl you