Web コンポーネントでマッピング アプリを構築

出典:Calcite Design System - Construct a mapping app with web components

Calcite コンポーネントと ArcGIS Maps SDK for JavaScript の Map コンポーネントを使用して、Web コンポーネントでマッピング アプリケーションの UI を構築する方法をご紹介します。

Calcite コンポーネントを使用して、マッピング アプリケーションのユーザー エクスペリエンスを向上させ、インタラクションを促進します。このチュートリアルでは、アプリの作成を効率化するためのユーザー インタフェースとマップ コンポーネントに焦点を当て、ArcGIS Maps SDK for JavaScript の予備知識は必要ありません。ArcGIS Maps SDK for JavaScript を初めてお使いになる場合は、このアプリケーションで使用されている同様のマッピングをコンセプトに扱った素晴らしいチュートリアルをご覧ください。

前提条件

ArcGIS 開発者アカウント
このチュートリアルで使用するサービスにアクセスするには、無料の ArcGIS Location Platform アカウントまたは ArcGIS Online 組織のアカウントが必要です。

ステップ

新しいペンの作成

  1. CodePen に移動し、マッピングアプリケーション用の新しいペンを作成します。

HTML の追加

  1. CodePen > HTML で、地図を表示する arcgis-map コンポーネントを含むページを作成するための HTML と CSS を追加してください。

  2. arcgis-map コンポーネントに id を追加して、アプリ開発全体で参照できるようにし、CSS を使って幅と高さをブラウザーのウィンドウに合わせて設定し、さらにアプリのスタイリングを補うために Flexbox を使用してください。

CodePen では、<!DOCTYPE html> タグは必須ではありません。別のエディターを使用している場合や、ローカル サーバーでページを運営している場合は、必ずこのタグを HTML ページの先頭に追加してください。

<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
    <title>Calcite Components: Construct a mapping app with web components</title>
  </head>
  <style>
    html,
    body,
    #mapEl {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
      display: flex;
    }
  </style>
  <body>
    <arcgis-map id="mapEl"></arcgis-map>
  </body>
  <script type="module">
  </script>
</html>
  1. <head> 要素に、Calcite コンポーネントと ArcGIS Maps SDK for JavaScript への参照を追加します。
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
  <title>Calcite Components: Create a mapping app with web components</title>

  <!-- 追加開始 -->
  <script src="https://js.arcgis.com/calcite-components/3.2.1/calcite.esm.js" type="module"></script>
  <script src="https://js.arcgis.com/4.33/"></script>
  <link rel="stylesheet" href="https://js.arcgis.com/4.33/esri/themes/light/main.css" />
  <!-- 追加終了 -->

</head>
  1. 次に、ArcGIS Maps SDK for JavaScript のマップ コンポーネントへの参照を追加します。
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
  <title>Calcite Components: Create a mapping app with web components</title>

  <script src="https://js.arcgis.com/calcite-components/3.2.1/calcite.esm.js" type="module"></script>
  <script src="https://js.arcgis.com/4.33/"></script>
  <link rel="stylesheet" href="https://js.arcgis.com/4.33/esri/themes/light/main.css" />
  <!-- 追加開始 -->
  <script type="module" src="https://js.arcgis.com/4.33/map-components"></script>
  <!-- 追加終了 -->

</head>

API キーの使用

開発者アカウントを使用している場合、ArcGIS サービスにアクセスするには API キーが必要です。ArcGIS Online の組織に関連付けられているアカウントがある場合は、この手順を省略できます。

  1. セキュアなリソースにアクセスできるアプリを作るには、セキュリティと認証を始めるをご覧ください。
  2. CodePen > <script> に戻り、esriConfig クラスをインポートします。
  3. apiKey プロパティを設定します。
<script type="module">
  // 追加開始
  const [esriConfig] = await $arcgis.import([
    "@arcgis/core/config.js"
  ]);
  esriConfig.apiKey = "YOUR_API_KEY";
  // 追加終了
</script>

マップの表示

マップはこのアプリケーションの中心です。HTML の追加で追加したCSSは、マップをウィンドウの幅と高さいっぱいに表示します。また、マップと連動する ArcGIS Maps SDK for JavaScript のマップ コンポーネントも追加します。

  1. <body> 内で、item-id 属性を使って arcgis-map コンポーネントを初期化します。この属性は Web マップのアイテム ID を指定します。
<body>
    <!-- 更新開始 -->
    <arcgis-map id="mapEl" item-id="03d584a7c9874b44821c6a766c3bbc11">

    </arcgis-map>
    <!-- 更新終了 -->
</body>
  1. 次に、arcgis-zoom コンポーネントを追加し、arcgis-map コンポーネントに対する位置を設定します。
<body>
    <arcgis-map id="mapEl" item-id="03d584a7c9874b44821c6a766c3bbc11">
        <!-- 追加開始 -->
        <arcgis-zoom position="top-left"></arcgis-zoom>
        <!-- 追加終了 -->
    </arcgis-map>
</body>

この時点でアプリケーションはマップを表示します。 次に、Calcite コンポーネントを使ってアプリのユーザー インターフェイスを構築します。

レイアウトの作成

レイアウトを作るために、スロットを使ってページ上の他のコンポーネントを整理する calcite-shell を使います。スロットは Web コンポーネントの概念であり、コア コンセプトのセクションに簡単な説明があります。Calcite コンポーネントにスロットがある場合は、その一覧がリファレンス ページに記載されています。たとえば、こちらが シェルのスロットです。

  1. calcite-shell コンポーネントを追加し、content-behind 属性を設定して、ユーザーがシェルの背後にある地図と操作できるようにします。
<body>
    <!-- 追加開始 -->
    <calcite-shell content-behind>
    <!-- 追加終了 -->
        <arcgis-map id="mapEl" item-id="03d584a7c9874b44821c6a766c3bbc11">
            <arcgis-zoom position="top-left"></arcgis-zoom>
        </arcgis-map>
    <!-- 追加開始 -->
     </calcite-shell>
    <!-- 追加終了 -->
</body>
  1. 次に、calcite-shell-panel コンポーネントを追加し、それをシェルの "panel-end" スロットに配置します。

  2. 次に、シェル パネルの displayMode 属性を "float" に設定して、コンテンツが地図の上に浮かんで表示されるようにします。

    <calcite-shell content-behind>
        <!-- 追加開始 -->
        <calcite-shell-panel id="shell-panel-nav" slot="panel-end" display-mode="float" height="l">

        </calcite-shell-panel>
        <!-- 追加終了 -->
        <arcgis-map id="mapEl" item-id="03d584a7c9874b44821c6a766c3bbc11">
            <arcgis-zoom position="top-left"></arcgis-zoom>
        </arcgis-map>
     </calcite-shell>
  1. calcite-panel コンポーネントを追加します。heading に Web マップのタイトルを動的に入力するために id を指定し、初期化時にコンポーネントを隠すために hidden 属性を追加します。

  2. 次に、calcite-icon をパネルの "header-actions-start" スロットに挿入します。

  3. 次に、calcite-action-bar をパネルの "action-bar" スロットに挿入します。ここに calcite-action を追加して、マップ コンポーネントを表示できるようにします。

  4. 各アクションに、一意の data-action-id の値を追加する。

    <calcite-shell content-behind>

        <calcite-shell-panel id="shell-panel-nav" slot="panel-end" display-mode="float" height="l">
            <!-- 追加開始-->
            <calcite-panel id="app-heading" hidden>
                <calcite-icon id="logo-icon" slot="header-actions-start" icon="explore" text-label="explore"></calcite-icon>
                <calcite-action-bar id="map-actions" slot="action-bar" layout="horizontal" expand-disabled>
                    <calcite-action icon="layers" text="Layers" data-action-id="layers"></calcite-action>
                    <calcite-action icon="basemap" text="Basemaps" data-action-id="basemaps"></calcite-action>
                    <calcite-action icon="legend" text="Legend" data-action-id="legend"></calcite-action>
                    <calcite-action icon="bookmark" text="Bookmarks" data-action-id="bookmarks"></calcite-action>
                    <calcite-action icon="print" text="Print" data-action-id="print"></calcite-action>
                    <calcite-action icon="information" text="About" data-action-id="information"></calcite-action>
              </calcite-action-bar>
            </calcite-panel>
            <!-- 追加開始-->
        </calcite-shell-panel>

マップ コンポーネントの追加

レイアウトをさらに構築するために、ユーザーが calcite-action に操作したときに表示されるマップ コンポーネントを追加します。

  1. はじめに calcite-block コンポーネントを追加する。

    • コンテンツを表示するために expanded 属性を追加します。
    • ユニークな heading を付けます。
    • 対応する data-action-id の値を、ブロックの data-block-id 属性に指定します。
    • アプリの初期化時にコンポーネントとそのコンテンツが表示されないように、hidden 属性を追加します。
  2. calcite-block に、arcgis-layer-list マップ コンポーネントをスロットに挿入します。

    • reference-element にマップ コンポーネントの id に設定します。
        <calcite-shell-panel id="shell-panel-nav" slot="panel-end" display-mode="float" height="l">
            <calcite-panel id="app-heading" hidden>
                <calcite-icon id="logo-icon" slot="header-actions-start" icon="explore" text-label="explore"></calcite-icon>
                <calcite-action-bar id="map-actions" slot="action-bar" layout="horizontal" expand-disabled>
                    <calcite-action icon="layers" text="Layers" data-action-id="layers"></calcite-action>
                    <calcite-action icon="basemap" text="Basemaps" data-action-id="basemaps"></calcite-action>
                    <calcite-action icon="legend" text="Legend" data-action-id="legend"></calcite-action>
                    <calcite-action icon="bookmark" text="Bookmarks" data-action-id="bookmarks"></calcite-action>
                    <calcite-action icon="print" text="Print" data-action-id="print"></calcite-action>
                    <calcite-action icon="information" text="About" data-action-id="information"></calcite-action>
              </calcite-action-bar>
            </calcite-panel>

            <!-- 追加開始 -->
            <!-- ArcGIS Maps SDK for JavaScript コンポーネントを含むマップ固有のブロック -->
            <calcite-block expanded heading="Layers" data-block-id="layers" hidden>
                <arcgis-layer-list drag-enabled reference-element="mapEl" visibility-appearance="checkbox"></arcgis-layer-list>
            </calcite-block>
            <!-- 追加終了 -->
        </calcite-shell-panel>
  1. ステップ 1 と 2 を繰り返して、calcite-block コンポーネントを追加し、arcgis-basemap-galleryarcgis-legendarcgis-bookmarks、および arcgis-print コンポーネントをそれぞれ含めます。
            <!-- ArcGIS Maps SDK for JavaScript コンポーネントを含むマップ固有のブロック -->
            <calcite-block expanded heading="Layers" data-block-id="layers" hidden>
                <arcgis-layer-list drag-enabled reference-element="mapEl" visibility-appearance="checkbox"></arcgis-layer-list>
            </calcite-block>

            <!-- 追加開始 -->
            <calcite-block expanded heading="Basemaps" data-block-id="basemaps" hidden>
                <arcgis-basemap-gallery reference-element="mapEl"></arcgis-basemap-gallery>
            </calcite-block>
            <calcite-block expanded heading="Legend" data-block-id="legend" hidden>
                <arcgis-legend legend-style="classic" reference-element="mapEl"></arcgis-legend>
            </calcite-block>
            <calcite-block expanded heading="Bookmarks" data-block-id="bookmarks" hidden>
                <arcgis-bookmarks editing-enabled="false" reference-element="mapEl"></arcgis-bookmarks>
            </calcite-block>
            <calcite-block expanded heading="Print" data-block-id="print" hidden>
                <arcgis-print allowed-formats="all" allowed-layouts="all" include-default-templates="false"
                reference-element="mapEl"></arcgis-print>
            </calcite-block>
            <!-- 追加終了 -->

インフォメーション カードの作成

インフォメーション カードは、アプリのデータに関する情報をユーザーに提供できます。calcite-card を使用して Web マップの情報を表示します。このカードには、タイトル、サムネイル画像、説明、最終更新日、タグが動的に入力・整理されます。

  1. 他の地図コンポーネントと同様に、calcite-block コンポーネントを追加します。

    • コンテンツを表示するために expanded 属性を追加します。
    • ユニークな heading を付けます。
    • 対応する data-action-id の値を、ブロックの data-block-id 属性に指定します。
    • closed 属性を追加し、アプリの初期化時にコンポーネントとそのコンテンツが表示されないようにします。
  2. calcite-card コンポーネントを追加します。

  3. カードに以下の子要素を、固有の ID を付けて追加します。

    • カードの thumbnail スロットに img 要素を定義します。
    • 3 つの div 要素を追加してください。1 つは heading スロットに、もう 1 つは description スロットに、最後の 1 つは footer-end スロットに配置します。
      <calcite-block expanded heading="Print" data-block-id="print" hidden>
        <arcgis-print allowed-formats="all" allowed-layouts="all" include-default-templates="false"
          reference-element="mapEl"></arcgis-print>
      </calcite-block>

      <!-- 追加開始 -->
      <!-- Info block (populates with info from the web map) -->
      <calcite-block expanded heading="About the data" data-block-id="information" hidden>
        <calcite-card id="card-content">
          <img id="card-thumbnail" alt="Webmap thumbnail" slot="thumbnail" />
          <div id="card-heading" slot="heading">
            <!-- Dynamically populated -->
          </div>
          <div id="card-description" slot="description">
            <!-- Dynamically populated -->
          </div>
          <div id="card-tags" slot="footer-end">
            <!-- Dynamically populated -->
          </div>
        </calcite-card>
      </calcite-block>
      <!-- 追加終了 -->

    </calcite-shell-panel>

コンテンツの設定

アプリケーションにコンポーネントの追加が終わりました。パネルの見出しとインフォメーション カードに Web マップの内容を入力します。

  1. <script> タグで arcgis-map コンポーネントを宣言します。
<script type="module">

  // 追加開始
  const mapEl = document.getElementById("mapEl");
  // 追加終了

</script>
  1. マップの arcgisViewReadyChange イベントで、Web マップのコンテンツを取得するために、次の portalItem の定数を宣言してください。:titlethumbnailUrlsnippetmodified、および tags

  2. 次に、UI に値を追加します。

    • title は、パネルの見出しおよびカードの "heading" スロットに使用されます。
    • thumbnailUrl は、カードの画像(img)の src プロパティとして "thumbnail" スロットに追加されます。
    • snippetmodified は、カードの "description" スロットを補足します。
    • tags は、それぞれのタグを繰り返し処理して、カードの "footer-end" スロットに個別の calcite-chip コンポーネントを作成します。
<script type="module">

  const mapEl = document.getElementById("mapEl");

  // 追加開始
  mapEl.addEventListener("arcgisViewReadyChange", () => {
    const { title, thumbnailUrl, snippet, modified, tags } = mapEl.map.portalItem;
    document.getElementById("app-heading").heading = `${title} Explorer`;
    document.getElementById("card-heading").innerHTML = title;
    document.getElementById("card-thumbnail").src = thumbnailUrl;
    document.getElementById("card-description").innerHTML = `<p>${snippet}</p><p>Last modified on ${modified}.</p>`;
    tags.forEach(tag => {
      document.getElementById("card-tags").innerHTML += `<calcite-chip>${tag}</calcite-chip>`;
    });

  });
  // 追加終了

</script>

コンポーネントをインタラクティブにする

次のステップは、対応する calcite-action コンポーネントをクリックしたときに、マップ コンポーネントを含む calcite-block コンポーネントを表示します。

  1. calcite-action がクリックされたときに実行される関数を作成します。この関数は、現在表示されている calcite-block を非表示にし、クリックされたアクションに対応するブロックを表示します。ユーザーが現在アクティブなアクションをクリックした場合、対応するブロックは閉じられ、展開されたブロックは存在しなくなります。

このステップでは、上で追加したデータ属性を使って、アクション要素とブロック要素にアクセスするために属性セレクターを使用します。データ属性の値は、対応するマップコンポーネントの名前です。

  mapEl.addEventListener("arcgisViewReadyChange", () => {
    const { title, thumbnailUrl, snippet, modified, tags } = mapEl.map.portalItem;
    document.getElementById("app-heading").heading = `${title} Explorer`;
    document.getElementById("card-heading").innerHTML = title;
    document.getElementById("card-thumbnail").src = thumbnailUrl;
    document.getElementById("card-description").innerHTML = `<p>${snippet}</p><p>Last modified on ${modified}.</p>`;
    tags.forEach(tag => {
      document.getElementById("card-tags").innerHTML += `<calcite-chip>${tag}</calcite-chip>`;
    });

  });

  // 追加開始
  let activeWidget;
  const handleActionBarClick = ({ target }) => {
    if (target.tagName !== "CALCITE-ACTION") {
      return;
    }
    if (activeWidget) {
      document.querySelector(`[data-action-id=${activeWidget}]`).active = false;
      document.querySelector(`[data-block-id=${activeWidget}]`).hidden = true;
    }
    const nextWidget = target.dataset.actionId;
    if (nextWidget !== activeWidget) {
      document.querySelector(`[data-action-id=${nextWidget}]`).active = true;
      document.querySelector(`[data-block-id=${nextWidget}]`).hidden = false;
      activeWidget = nextWidget;
    } else {
      activeWidget = null;
    }
  };
  document.querySelector("calcite-action-bar").addEventListener("click", handleActionBarClick);
  // 追加終了

</script>

ローダー コンポーネントの追加

ここまでで、アプリケーションがインタラクティブになりました。Calcite コンポーネントを使用して、マップ コンポーネントを開いたり閉じたりできます。しかし、アプリケーションのロードには1秒かかるので、それをユーザーに伝える必要があります。

  1. 要素内で、シェルの終了タグの後に calcite-loader を追加して、コンポーネントを表示します。
     </calcite-shell>
     <!-- 追加開始 -->
     <calcite-loader></calcite-loader>
     <!-- 追加終了 -->
</body>
  1. arcgisViewReadyChange イベントの内部で、他の JavaScript コードの下に、calcite-loader コンポーネントを hidden プロパティを true に設定して非表示にし、calcite-panel を表示してください。マップとそのプロパティがアプリに読み込まれると、ローダーは非表示になり、パネルが UI に表示されます。
  mapEl.addEventListener("arcgisViewReadyChange", () => {
    const { title, thumbnailUrl, snippet, modified, tags } = mapEl.map.portalItem;
    document.getElementById("app-heading").heading = `${title} Explorer`;
    document.getElementById("card-heading").innerHTML = title;
    document.getElementById("card-thumbnail").src = thumbnailUrl;
    document.getElementById("card-description").innerHTML = `<p>${snippet}</p><p>Last modified on ${modified}.</p>`;
    tags.forEach(tag => {
      document.getElementById("card-tags").innerHTML += `<calcite-chip>${tag}</calcite-chip>`;
    });

    // 追加開始
    document.querySelector("calcite-loader").hidden = true;
    document.getElementById("app-heading").removeAttribute("hidden");
    // 追加終了

  });

スタイルの追加

<style> 要素内で、見出しの calcite-panel と情報の calcite-card のユーザー インターフェースを強化するために、追加の CSS を記述します。

  1. calcite-icon をパネルの "header-actions-start" にスロットしている場合、そのコンポーネントを整列させるために Flexbox の変数を追加します。

  2. 次に、パネルの幅と高さを設定するためのスタイルを追加します。

    • calcite-shell-panel に –calcite-shell-panel-min-width を追加します。
    • calcite-shell-panel がスマートフォンなどの小型デバイスに対応できるように、メディア クエリーを追加します。
    • data-block-id 属性を含む calcite-block コンポーネントに対して、max-height を設定します。
<style>

  html,
  body,
  #mapEl {
    padding: 0;
    margin: 0;
    height: 100%;
    width: 100%;
    display: flex;
  }


  /** 追加開始 */
  #logo-icon {
    align-self: center;
    height: auto;
    margin-inline-start: 0.5rem;
  }

  #shell-panel-nav {
    --calcite-shell-panel-min-width: 18rem;
  }

  @media (max-width: 400px) {
    #shell-panel-nav {
      --calcite-shell-panel-min-width: 80vw;
    }
  }

  calcite-block[data-block-id] {
    max-height: 50vh;
    overflow-y: auto;
  }
  /** 追加終了 */

</style>
  1. 最後に、calcite-card にスタイルを追加してください。具体的には、コンポーネントにパディングを追加し、CSS 変数を使ってフォント サイズを更新し、タグを flex-wrap で折り返すようにしてください。
<style>
  /** ~ 中略 ~  */
  calcite-block[data-block-id] {
    max-height: 50vh;
    overflow-y: auto;
  }


  /* 追加開始 */
  #card-heading {
    font-size: var(--calcite-font-size-md);
  }

  #card-description {
    font-size: var(--calcite-font-size);
  }

  #card-tags {
    flex-wrap: wrap;
  }
  /* 追加終了 */

</style>

アプリの実行

CodePen でコードを実行すると、アプリケーションが表示されます。

アプリケーションの読み込みが完了すると、マップが表示され、Web マップのタイトルと calcite-action-bar も一緒に表示されます。calcite-action コンポーネントをクリックすると、calcite-block コンポーネントが展開・折りたたみされます。これらのブロックには、ArcGIS Maps SDK for JavaScript のマップ コンポーネントが含まれています。