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>
      <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
 ...

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: 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 {
 ...

JavaScript

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

async function initMap() {
  await woosmap.map.importLibrary("maps");
  map = document.getElementById("map").innerMap;
  map.setOptions({
    mapTypeControl: true,
    styles: STYLE_PRESETS.lightgrey,
  });
  map.moveCamera({
    zoom: 15.64,
    center: centerLatLng,
  });
  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);
  // Restyling reloads the base style, which drops 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) {
  map.setOptions({ styles: STYLE_PRESETS[name] ?? [] });
}

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

  const config = LAYER_CONFIGS[provider];

  if (!config) {
  ...