Distance Isochrone

Sample code for Woosmap Map JavaScript API author(s): Woosmap

HTML

<!DOCTYPE html>
<html>
  <head>
    <title>Distance Isochrone</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta charset="utf-8" />

    <!-- jsFiddle will insert css and js -->
  </head>
  <body>
    <div id="app">
      <div id="selector">
        <div class="select-container">
          <span>mode </span>
          <select id="isochrone-mode-select">
            <option value="driving">Driving</option>
            <option value="walking">Walking</option>
            <option value="cycling">Cycling</option>
          </select>
        </div>
        <div class="select-container">
          <span>method </span>
          <select id="isochrone-method-select">
            <option value="time">Time</option>
            <option value="distance">Distance</option>
          </select>
        </div>
        <div class="select-container">
          <span>value </span>
          <input
            id="isochrone-distance-input"
            type="number"
            value="50"
            min="1"
            max="120"
          />
        </div>
        <div class="select-container">
          <small style="opacity: 0.5; padding: 0 5px"
            >click on the map to change isochrone origin</small
          >
        </div>
      </div>
      <wmp-map id="map"></wmp-map>
    </div>

    <script>
      ((g) => {
        let p;
        const w = window,
          d = document;
        const L = "importLibrary",
          CB = "__ib__";
        const E = "The Woosmap Maps JavaScript API";
        const woosmap = w.woosmap || (w.woosmap = {});
        const maps = woosmap.map || (woosmap.map = {});
        // Seed with the sample's configured libraries: some (e.g. widgets) are
        // not importLibrary() names and only load through the script URL.
        const libs = new Set(
            String(g.libraries || "")
              .split(",")
              .filter(Boolean),
          ),
          params = new URLSearchParams();
   ...

CSS

/*
 * Always set the map height explicitly to define the size of the element
 * that contains the map. `display: block` is required for <wmp-map>/<gmp-map>,
 * which default to inline like any other custom element outside a flex/grid
 * container (no-op for a plain <div>).
 */
#map {
  display: block;
  width: 100%;
  height: 100%;
}

/*
 * Optional: Makes the sample page fill the window.
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
  font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
}

#app {
  height: 100%;
}

#selector {
  position: absolute;
  top: 0px;
  left: 0;
  background-color: #fff;
  border-radius: 3px;
  box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.1);
  margin: 10px;
  padding: 5px;
  overflow: hidden;
  z-index: 1;
}

select {
  width: 100px;
}

input {
  width: 92px;
}

.select-container {
  padding: 2px 0;
  width: 100%;
  display: flex;
  justify-content: space-between;
}

#selector span {
  padding: 0 5px;
}

JavaScript

let map;
let methodSelect, modeSelect;
let distanceInput;
let marker;
let polyline;
let distanceService;
const centerLatLng = {
  lat: 51.5,
  lng: -0.234,
};

function createMarkerContent() {
  return new woosmap.map.marker.PinElement().element;
}

function createMarker(position, map) {
  const marker = new woosmap.map.marker.AdvancedMarkerElement({
    position,
    content: createMarkerContent(),
  });

  marker.setMap(map);
  return marker;
}

async function initMap() {
  await woosmap.map.importLibrary("maps");
  await woosmap.map.importLibrary("marker");
  map = document.getElementById("map").innerMap;
  map.moveCamera({
    zoom: 9,
    center: centerLatLng,
  });
  distanceService = new woosmap.map.DistanceService();
  marker = createMarker(centerLatLng, map);
  map.addListener("click", (e) => {
    marker.setMap(null);
    marker = createMarker(e.latlng, map);
    computeIsochrone(e.latlng);
  });

  const onChangeHandler = () => {
    computeIsochrone(marker.position.toJSON());
  };

  methodSelect = document.getElementById("isochrone-method-select");
  modeSelect = document.getElementById("isochrone-mode-select");
  distanceInput = document.getElementById("isochrone-distance-input");
  methodSelect.addEventListener("change", onChangeHandler);
  modeSelect.addEventListener("change", onChangeHandler);
  distanceInput.addEventListener("change", onChangeHandler);
  computeIsochrone(centerLatLng);
}

function computeIsochrone(origin) {
  if (
    parseInt(distanceInput.value) > 120 ||
    parseInt(distanceInput.value) <= 0
  ) {
    alert("Value should be between 1 and 120");
    return;
  }

  const isochroneRequest = {
    origin,
    method: methodSelect.value,
    travelMode: modeSelect.value,
    value: parseInt(distanceInput.value),
  };

  distanceService
    .getDistanceIsochrone(isochroneRequest)
    .then(displayIsochrone)
    .catch((error) => {
      console.error(error);
    });
}

function displayIsochrone(isochrone) {
  if (polyline) {
   ...