Voler vers un lieu

Déplacez la caméra à l'aide de vos propres boutons. flyTo anime le déplacement le long d'une courbe, fitBounds cadre un rectangle, et fitLayer cadre les données d'une couche sans que vous ayez à connaître de coordonnées. L'affichage de droite est alimenté par l'événement viewChanged : faites glisser la carte et observez la raison passer de command à user.

Ouvrir cet exemple seul

Points à remarquer

  • Les coordonnées sont toujours au format [longitude, latitude].
  • fitLayer cadre les données telles que filtrées actuellement : il se combine donc naturellement avec les segments et les filtres.
  • fitBounds et fitLayer conservent l'inclinaison de la caméra, sauf si vous indiquez où elle doit se poser : passez pitch: 0, bearing: 0 pour un cadrage à plat, nord en haut.
  • viewChanged porte une reason, ce qui permet à une synchronisation bidirectionnelle d'ignorer l'écho de ses propres commandes.

Le code

La page complète. Remplacez l'identifiant de publication par le vôtre, et demandez à l'auteur de la carte d'ajouter votre site à ses origines autorisées.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Fly to a location - Icon Map Embed API</title>
  <link rel="stylesheet" href="https://www.icon-map.com/embed-examples/examples.css"> <!-- demo styling only -->
</head>
<body>
  <div class="ex-bar">
    <span class="ex-label">Fly to</span>
    <button data-city="tokyo">Tokyo</button>
    <button data-city="london">London</button>
    <button data-city="lagos">Lagos</button>
    <button data-city="saopaulo">Sao Paulo</button>
    <button id="europe">Frame Europe</button>
    <button id="cities">Frame every city</button>
    <button id="home">Home</button>
    <span class="ex-spacer"></span>
    <pre class="ex-readout" id="readout"></pre>
  </div>
  <div class="ex-main"><div id="map"></div></div>

  <script src="https://www.icon-map.com/js/iconmap-embed/2/iconmap-embed.umd.min.js"></script>
  <script>
    const el = document.getElementById("map");
    const map = IconMapEmbed.embed(el, {
      publishId: "pub_...",
      // The map is a globe: let this page's own background show in the space around it.
      background: "transparent",
      // Start calm: hide the map's own panels and cards for this demo.
      chrome: { legend: false, layerControl: false, bookmarksBar: false, tourTransport: false },
      visibility: { visuals: { "chart-continent": false, "slicer-continent": false, "slicer-size": false, "slicer-capital": false } },
      events: ["viewChanged"],
    });
    map.ready.catch((error) => console.error(error.code, error.message));

    const places = {
      tokyo:    { center: [139.75, 35.69],  zoom: 7.5, pitch: 40, bearing: -20 },
      london:   { center: [-0.12, 51.5],    zoom: 7.5, pitch: 30, bearing: 15 },
      lagos:    { center: [3.39, 6.45],     zoom: 7,   pitch: 35, bearing: 0 },
      saopaulo: { center: [-46.63, -23.56], zoom: 7.5, pitch: 40, bearing: 25 },
    };

    // flyTo animates along a curve; setView jumps (or eases with animate: true).
    for (const button of document.querySelectorAll("[data-city]")) {
      button.onclick = () => map.flyTo({ ...places[button.dataset.city], durationMs: 3500 });
    }

    // fitBounds frames a box: [[west, south], [east, north]]. pitch and bearing are where the camera
    // LANDS - without them a frame keeps the tilt of the flight before it.
    document.getElementById("europe").onclick = () =>
      map.fitBounds({ bounds: [[-11, 35], [40, 71]], padding: 30, pitch: 0, bearing: 0 });

    // fitLayer frames a layer's data as currently filtered - no coordinates needed.
    document.getElementById("cities").onclick = () =>
      map.fitLayer({ layerId: "cities", padding: 20, pitch: 0, bearing: 0 });

    document.getElementById("home").onclick = () =>
      map.setView({ center: [18, 22], zoom: 2.05, pitch: 0, bearing: 0, animate: true });

    // viewChanged fires when the camera settles. `reason` says who moved it.
    map.on("viewChanged", (view) => {
      document.getElementById("readout").textContent =
        `${view.center[0].toFixed(2)}, ${view.center[1].toFixed(2)}  z${view.zoom.toFixed(1)}  ` +
        `pitch ${Math.round(view.pitch)}  (${view.reason})`;
    });
  </script>
</body>
</html>

Pour aller plus loin