Map External Layer

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

HTML

<!DOCTYPE html>
<html>
  <head>
    <title>Map External Layer</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">
        <h3 class="panel-title">Map options</h3>

        <label class="select-container">
          <span class="label">Map style</span>
          <select id="woosmap-style-select">
            <option value="default">Default</option>
            <option value="lightgrey" selected>Light Grey</option>
            <option value="night">Transit By Night</option>
            <option value="retro">Retro</option>
          </select>
        </label>

        <label class="select-container">
          <span class="label">Overlay layer</span>
          <select id="layer-provider-select">
            <option value="pistes">OpenSnowMap ski runs</option>
            <option value="temperature">OpenWeather temperature</option>
            <option value="precipitation">OpenWeather precipitation</option>
          </select>
        </label>

        <label class="select-container">
          <span class="label">Opacity</span>
          <div class="opacity-control">
            <input
              id="opacity-value-input"
              type="range"
              value="1"
              step="0.05"
              min="0"
              max="1"
            />
            <span id="opacity-value-display">100%</span>
          </div>
        </label>
      </div>
      <div id="map"></div>
    </div>

    <script
      src="https://sdk.woosmap.com/map/map.js?key=woos-e1e5490b-19d1-34f8-9955-fd5cfc8c880f&callback=initMap"
      defer
    ></script>
  </body>
</html>

CSS

/*
 * Always set the map height explicitly to define the size of the div element
 * that contains the map.
 */
#map {
  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: 0;
  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;
  width: 220px;
  padding: 12px;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

.panel-title {
  margin: 0 0 10px;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #5f6368;
}

.select-container {
  display: flex;
  flex-direction: column;
  margin-bottom: 10px;
}
.select-container:last-child {
  margin-bottom: 0;
}

.select-container .label {
  font-size: 0.8125rem;
  font-weight: 500;
  color: #202124;
  margin-bottom: 4px;
}

.select-container select {
  width: 100%;
  height: 30px;
  box-sizing: border-box;
  border: 1px solid #dadce0;
  border-radius: 4px;
  padding: 0 8px;
  font-size: 0.8125rem;
  background: #fff;
  cursor: pointer;
}
.select-container select:hover {
  border-color: #b8bcc1;
}
.select-container select:focus {
  outline: none;
  border-color: #1a73e8;
}

.opacity-control {
  display: flex;
  align-items: center;
  gap: 8px;
}

.opacity-control input[type=range] {
  flex: 1;
  accent-color: #1a73e8;
  cursor: pointer;
}

#opacity-value-display {
  font-variant-numeric: tabular-nums;
  font-size: 0.8125rem;
  color: #5f6368;
  min-width: 36px;
  text-align: right;
}

JavaScript

const openWeatherMapKey = "723abb7941260adc84c92a1f526bdabb";
let map;
let styleSelect;
let layerSelect;
let opacityInput;
let opacityDisplay;
const centerLatLng = {
  lat: 45.126643,
  lng: 6.073999,
};

function initMap() {
  map = new window.woosmap.map.Map(document.getElementById("map"), {
    zoom: 15.64,
    center: centerLatLng,
    mapTypeControl: true,
    styles: STYLE_PRESETS.lightgrey,
  });
  styleSelect = document.getElementById("woosmap-style-select");
  layerSelect = document.getElementById("layer-provider-select");
  opacityInput = document.getElementById("opacity-value-input");
  opacityDisplay = document.getElementById("opacity-value-display");
  updateOpacityDisplay();
  applyLayer(layerSelect.value, readOpacity());
  styleSelect.addEventListener("change", onStyleChange);
  layerSelect.addEventListener("change", onLayerChange);
  opacityInput.addEventListener("input", updateOpacityDisplay);
  opacityInput.addEventListener("change", onOpacityChange);
}

function updateOpacityDisplay() {
  const opacity = parseFloat(opacityInput.value);

  opacityDisplay.textContent = `${Math.round(opacity * 100)}%`;
}

function readOpacity() {
  const opacity = parseFloat(opacityInput.value);
  return isNaN(opacity) ? 1 : opacity;
}

function onStyleChange() {
  applyStyle(styleSelect.value);
  // Recreating the map wipes overlays — reapply the current layer.
  applyLayer(layerSelect.value, readOpacity());
}

function onLayerChange() {
  const view = LAYER_VIEWS[layerSelect.value];

  if (view) {
    map.flyTo(view);
  }

  applyLayer(layerSelect.value, readOpacity());
}

function onOpacityChange() {
  applyLayer(layerSelect.value, readOpacity());
}

function applyStyle(name) {
  const styles = STYLE_PRESETS[name] ?? [];

  map = new window.woosmap.map.Map(document.getElementById("map"), {
    zoom: map.getZoom(),
    center: map.getCenter(),
    mapTypeControl: true,
    styles,
  });
}

function applyLayer(provider, opacity) {
  map.overlayMapTypes.clear();

...