Routing API + MapLibre GL

Build a route and display results on MapLibre GL map

by Geoapify

HTML

<link rel="stylesheet" href="https://unpkg.com/maplibre-gl@1.15.2/dist/maplibre-gl.css">
<script src="https://unpkg.com/maplibre-gl@1.15.2/dist/maplibre-gl.js"></script>
<div class="route-settings">
  <label class="switch">
    <input id="showDetails" type="checkbox" onclick="drawRoute()">
    <span class="slider round"></span>
  </label> 
  Show route details
</div>
<div id="my-map"></div>

CSS

html,
body {
  margin: 0;
  padding: 0;

  height: 100%;
  display: flex;
  flex-direction: column;
}

.route-settings {
  padding: 5px
}

#my-map {
  flex: 1;
}


/* The switch - the box around the slider */
.switch {
  position: relative;
  display: inline-block;
  width: 30px;
  height: 17px;
}

/* Hide default HTML checkbox */
.switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

/* The slider */
.slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #ccc;
  -webkit-transition: .4s;
  transition: .4s;
}

.slider:before {
  position: absolute;
  content: "";
  height: 13px;
  width: 13px;
  left: 2px;
  bottom: 2px;
  background-color: white;
  -webkit-transition: .4s;
  transition: .4s;
}

input:checked+.slider {
  background-color: #2196F3;
}

input:focus+.slider {
  box-shadow: 0 0 1px #2196F3;
}

input:checked+.slider:before {
  -webkit-transform: translateX(13px);
  -ms-transform: translateX(13px);
  transform: translateX(13px);
}

/* Rounded sliders */
.slider.round {
  border-radius: 17px;
}

.slider.round:before {
  border-radius: 50%;
}

JavaScript

// The API Key provided is restricted to JSFiddle website
// Get your own API Key on https://myprojects.geoapify.com
const myAPIKey = "6dc7fb95a3b246cfa0f3bcef5ce9ed9a";

const map = new maplibregl.Map({
  container: 'my-map',
  style: `https://maps.geoapify.com/v1/styles/klokantech-basic/style.json?apiKey=${myAPIKey}`,
  center: [-72.79419772520356, 44.53361448499783],
  zoom: 14
});
map.addControl(new maplibregl.NavigationControl());

const popup = new maplibregl.Popup();

// calculate and display routing:
// from 38.937165,-77.045590 (1208 Hourglass Drive, Stowe, VT 05672, United States of America)
const fromWaypoint = [-72.78056761690857, 44.53000255267429]; // longitude, latutude
const fromWaypointMarker = new maplibregl.Marker().setLngLat(fromWaypoint)
  .setPopup(new maplibregl.Popup().setText(
    '1208 Hourglass Drive, Stowe, VT 05672, United States of America'
  )).addTo(map);


// to 38.881152,-76.990693 (Switchback, Stowe, VT 05672-5111, United States of America)
const toWaypoint = [-72.80797096598127, 44.536552001130076]; // longitude, latutude
const toWaypointMarker = new maplibregl.Marker().setLngLat(toWaypoint)
  .setPopup(new maplibregl.Popup().setText(
    'Switchback, Stowe, VT 05672-5111, United States of America'
  )).addTo(map);

let routeData;
let routeStepsData;
let instructionsData;
let stepPointsData;

fetch(`https://api.geoapify.com/v1/routing?waypoints=lonlat:${fromWaypoint.join(",")}|lonlat:${toWaypoint.join(",")}&mode=hike&details=route_details,elevation&apiKey=${myAPIKey}`).then(res => res.json()).then(routeResult => {
  routeData = routeResult;
  const steps = [];
  const instructions = [];
  const stepPoints = [];

  routeData.features[0].properties.legs.forEach((leg, legIndex) => {
    const legGeometry = routeData.features[0].geometry.coordinates[legIndex];
    leg.steps.forEach((step, index) => {
      if (step.instruction) {
        instructions.push({
          "type": "Feature",
          "geometry": {
            "type":...