ArcGIS Maps SDK コンポーネントで Web アプリを構築

553
0
02-20-2024 09:37 PM
Labels (1)

ArcGIS Maps SDK コンポーネントで Web アプリを構築

202310月にリリースされた ArcGIS Maps SDK for JavaScript バージョン 4.28 にて、最小限のコードで Web マッピング アプリケーションを構築するための全く新しい Web コンポーネントである、ArcGIS Maps SDK コンポーネントがベータ版にてリリースされました。

本記事では、ArcGIS Maps SDK コンポーネントについて、米国 Esri 社が公開している「Build GIS Web Apps with JavaScript Maps SDK components」の記事を翻訳してご紹介します。

 

ArcGIS Maps SDK for JavaScript とは?

ArcGIS Maps SDK for JavaScript は、開発者が魅力的な Web GIS エクスペリエンスを構築できる強力なマッピングおよび空間解析テクノロジーです。Esri では、この基盤となるSDKを使用して地理空間アプリケーションを開発しています。これらのアプリケーションにより、ユーザーは地図の作成、分析、共同作業、共有を行うことができます。

Web コンポーネントとは?

Web コンポーネントは、W3C によって導入された一連の技術であり、再利用可能でフレームワークにとらわれないカスタム HTML エレメントの構築を可能にします。強力なカプセル化、カスタム機能、HTML DOM API との完全な互換性を提供します。SDKで使用しているWeb コンポーネントには、主に次の3つの技術があります。

開発者が独自の HTML エレメントをカスタムした動作で定義できるようにします。

JavaScript SDKCSSをカスタム エレメント内にカプセル化し、DOM の他の部分に影響を与えないようにします。

テンプレートを含むカスタム エレメントのインスタンスで使用できるマークアップ チャンクの定義を許可します。

要約すると、Web コンポーネントは複雑な HTML とそれに関連する CSS JavaScriptを簡素化するのに適しています。次に、JavaScript Maps SDK と、SDK の新機能である Web コンポーネントについて説明します。

ArcGIS Maps SDK for JavaScript コンポーネント

10月にリリースされた ArcGIS Maps SDK for JavaScript(v4.28) では、標準ベースの Webコンポーネントのベータ版が導入されました。JavaScript Maps SDKコンポーネントの初期リリースは、JavaScript Maps SDK の一部を再利用可能なHTML エレメントに拡張する3つのパッケージで構成されています。

 

  • Web コンポーネントには、マップシーン、そして Web コンポーネントとしてラップされたすべての JavaScript Maps SDK ウィジェットが含まれています。
  • コーディング コンポーネントは、コーディングという行為全般をサポートすることを目的としています。現在、Arcade エディター コンポーネントが主な製品です。
  • 共通コンポーネントは、他の JavaScript Maps SDK コンポーネント パッケージと一緒に使用することで、追加機能を提供することができます。

 

 

<arcgis-map item-id="05e015c5f0314db9a487a9b46cb37eca"/>

 

RyukiHIRAMATSU_0-1708492740822.png

 

 

開発者がSDKWebコンポーネントを使用する理由

Webコンポーネントは、米国 Esri で豊かな歴史を刻んできました。開発プロセスの基本的な構成要素として Web コンポーネントを採用することで、特定のアプリケーション フレームワーク(ReactAngularVue など)に縛られることなく、再利用可能なHTML エレメントを幅広く作成できるようになりました。また、Calcite Design System のコンポーネントも多用しています。このように Web コンポーネントを採用することで、開発者を統一し、異なる ArcGIS 製品間で一貫したユーザー エクスペリエンスを実現しています。

 

プログラミング パラダイムという点では、JavaScript Maps SDK のコンポーネントは宣言型ファーストのアプローチを提供し、JavaScript Maps SDK は伝統的に命令型/手続き型アプローチを主に採用してきました。コンポーネントを使用することで、開発者は、定型的なコードの必要性を減らし、代わりに必要なタスクのすべてではないにしても、HTML マークアップを使用してほとんどを達成することに集中し、事前に構築されたArcGIS エクスペリエンスを信頼することができます。これにより、ArcGIS の機能をアプリに統合するプロセスが簡素化されます。一方、JavaScript Maps SDK では、開発者が詳細な命令を記述できるため、アプリケーションの状態や実行の流れを広範囲に制御できます。

 

コンポーネントがアプリに与える影響とは?

命令形アプローチを使った基本的な Web マップの作成方法について理解を深めるために、以下の例をご覧ください。JavaScript は、地図とそのウィジェットを表示する <div id="viewDiv"></div> コンテナ エレメントを操作するために使用されます。

 

JavaScript Maps SDKで構築された Web マップ

 

<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1, maximum-scale=1,user-scalable=no"
    />
    <title>ArcGIS Maps SDK for JavaScript 4.28</title>
    <style>
      html,
      body,
      #viewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
        overflow: hidden;
      }
    </style>
    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.28/esri/themes/light/main.css"
    />
    <script src="https://js.arcgis.com/4.28/"></script>
    <script>
      require([
        "esri/views/MapView",
        "esri/widgets/Legend",
        "esri/widgets/Search",
        "esri/WebMap",
      ], (MapView, Legend, Search, WebMap) => {
        const webmap = new WebMap({
          portalItem: {
            id: "05e015c5f0314db9a487a9b46cb37eca",
          },
        });
        const view = new MapView({
          container: "viewDiv",
          map: webmap,
        });
        const search = new Search({
          view,
        });
        const legend = new Legend({
          view,
        });
        view.ui.add(search, "top-right");
        view.ui.add(legend, "bottom-left");
      });
    </script>
  </head>

  <body>
    <div id="viewDiv"></div>
  </body>
</html>

 

 

この2つのパラダイムの違いを説明するために、先ほどの例を考え、@ArcGIS/map-components パッケージを使ってどのように書き換えるかを示します。

 

JavaScript Maps SDK コンポーネントで構築された Web マップ

 

<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0"
    />
    <title>Map components</title>
    <style>
      html,
      body {
        padding: 0;
        margin: 0;
        width: 100vw;
        height: 100vh;
      }
    </style>
    <!-- Load the ArcGIS Maps SDK for JavaScript -->
    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.28/esri/themes/light/main.css"
    />
    <script src="https://js.arcgis.com/4.28/"></script>
    <!-- Load the Map Components -->
    <script
      type="module"
      src="https://js.arcgis.com/map-components/4.28/arcgis-map-components.esm.js"
    ></script>
  </head>

  <body>
    <arcgis-map item-id="05e015c5f0314db9a487a9b46cb37eca">
      <arcgis-search position="top-right" />
      <arcgis-legend position="bottom-left" />
    </arcgis-map>
  </body>
</html>

 

RyukiHIRAMATSU_1-1708492923673.png

 

 

Mapコンポーネントでお分かりのように、同じ解決策を達成するために JavaScript は不要であり、viewDiv コンテナ エレメントも必要ありません。また、WebMap MapView を別々に初期化する必要もなくなります。この例は純粋に Web コンポーネントで書かれていますが、基礎となる API はまだ利用可能であり、命令型と宣言型のプログラミング パラダイムのバランスを作り出していることに注意することが重要です。この柔軟性により、両方のアプローチのメリットを受けることができます。

 

<body>
  <arcgis-map item-id="05e015c5f0314db9a487a9b46cb37eca">
    <arcgis-search position="top-right" />
    <arcgis-legend position="bottom-left" />
  </arcgis-map>
  <script>
    // Access the underlying API to get the thumbnail url of the map
    const mapElm = document.querySelector("arcgis-map");
    mapElm.addEventListener("viewReady", async (event) => {
      const { view } = event.detail;
      const { map } = view;
      console.log(map.thumbnailUrl);
    });
  </script>
</body>

 

 

 

アプリと Calcite Design System を統合

Calcite Design System JavaScript Maps SDK のアプリと統合して、包括的で魅力的な GIS エクスペリエンスを構築できます。命令型アプローチでは、JavaScriptで作成し操作するために、定型的なコードと <div/>  HTML エレメントが必要であることに注意してください。

JavaScript Maps SDKとCalciteで作られた Web マップ

 

<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1, maximum-scale=1, user-scalable=no"
    />
    <title>Calcite and map components (imperative)</title>
    <script
      src="https://js.arcgis.com/calcite-components/1.9.2/calcite.esm.js"
      type="module"
    ></script>
    <link
      rel="stylesheet"
      href="https://js.arcgis.com/calcite-components/1.9.2/calcite.css"
    />
    <script src="https://js.arcgis.com/4.28/"></script>
    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.28/esri/themes/light/main.css"
    />
  </head>

  <style>
    html,
    body,
    #viewDiv {
      height: 100%;
      width: 100%;
      padding: 0;
      margin: 0;
    }
  </style>

  <body>
    <calcite-shell>
      <calcite-navigation slot="header">
        <calcite-navigation-logo slot="logo" />
      </calcite-navigation>
      <div id="viewDiv"></div>
    </calcite-shell>
    <script>
      require(["esri/WebMap", "esri/widgets/LayerList", "esri/views/MapView"], (
        WebMap,
        LayerList,
        MapView
      ) => {
        const webMap = new WebMap({
          portalItem: {
            id: "e691172598f04ea8881cd2a4adaa45ba",
          },
        });
        const view = new MapView({
          container: "viewDiv",
          map: webMap,
          zoom: 4,
        });
        view.when(() => {
          const portalItem = view.map.portalItem;
          const navigationLogo = document.querySelector(
            "calcite-navigation-logo"
          );
          navigationLogo.heading = portalItem.title;
          navigationLogo.description = portalItem.snippet;
          navigationLogo.thumbnail = portalItem.thumbnailUrl;
          const layer = view.map.layers.find(
            (layer) => layer.id === "Accidental_Deaths_8938"
          );
          layer.popupTemplate.title = "Accidental Deaths";
          const layerList = new LayerList({
            view,
          });
          view.ui.add(layerList, "top-right");
          layerList.listItemCreatedFunction = (event) => {
            const item = event.item;
            if (item.layer.type !== "group") {
              item.panel = {
                content: "legend",
              };
            }
          };
        });
      });
    </script>
  </body>
</html>

 

 

JavaScript Maps SDK コンポーネントと Calcite で作られた Webマップ

 

<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1, maximum-scale=1, user-scalable=no"
    />
    <title>Calcite and map components (declarative)</title>
    <script
      src="https://js.arcgis.com/calcite-components/1.9.2/calcite.esm.js"
      type="module"
    ></script>
    <link
      rel="stylesheet"
      href="https://js.arcgis.com/calcite-components/1.9.2/calcite.css"
    />
    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.28/esri/themes/light/main.css"
    />
    <script src="https://js.arcgis.com/4.28/"></script>
    <script
      type="module"
      src="https://js.arcgis.com/map-components/4.28/arcgis-map-components.esm.js"
    ></script>
  </head>

  <style>
    html,
    body,
    arcgis-map {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }
  </style>

  <body>
    <calcite-shell>
      <calcite-navigation slot="header">
        <calcite-navigation-logo slot="logo" />
      </calcite-navigation>
      <arcgis-map item-id="e691172598f04ea8881cd2a4adaa45ba" zoom="4">
        <arcgis-layer-list position="top-right" />
      </arcgis-map>
    </calcite-shell>
    <script type="module">
      const mapElement = document.querySelector("arcgis-map");
      const layerListElement = document.querySelector("arcgis-layer-list");
      layerListElement.addEventListener("widgetReady", (event) => {
        const layerList = event.detail.widget;
        layerList.listItemCreatedFunction = (event) => {
          const item = event.item;
          if (item.layer.type !== "group") {
            item.panel = {
              content: "legend",
            };
          }
        };
      });
      mapElement.addEventListener("viewReady", async (event) => {
        const view = event.detail.view;
        const portalItem = view.map.portalItem;
        const navigationLogo = document.querySelector(
          "calcite-navigation-logo"
        );
        navigationLogo.heading = portalItem.title;
        navigationLogo.description = portalItem.snippet;
        navigationLogo.thumbnail = portalItem.thumbnailUrl;
        const layer = view.map.layers.find(
          (layer) => layer.id === "Accidental_Deaths_8938"
        );
        layer.popupTemplate.title = "Accidental Deaths";
      });
    </script>
  </body>
</html>

 

RyukiHIRAMATSU_2-1708493155479.png 

 

ウィジェットをマップやシーンに簡単に関連付ける

JavaScript Maps SDK コンポーネントは、アプリの可読性とシンプルさをさらに向上させます。例えば、ウィジェットは reference-element(詳細はプロパティ タブを参照)を <arcgis-map/> id に設定することでマップにアクセスできます。これはウィジェットが<arcgis-map/> コンポーネントの外側にある場合に便利です。

地図に関連した凡例

 

<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1, maximum-scale=1, user-scalable=no"
    />
    <title>Calcite and map components (declarative)</title>
    <script
      src="https://js.arcgis.com/calcite-components/1.9.2/calcite.esm.js"
      type="module"
    ></script>
    <link
      rel="stylesheet"
      href="https://js.arcgis.com/calcite-components/1.9.2/calcite.css"
    />
    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.28/esri/themes/light/main.css"
    />
    <script src="https://js.arcgis.com/4.28/"></script>
    <script
      type="module"
      src="https://js.arcgis.com/map-components/4.28/arcgis-map-components.esm.js"
    ></script>
  </head>

  <style>
    html,
    body,
    arcgis-map {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }
  </style>

  <body>
    <calcite-shell content-behind>
      <calcite-shell-panel slot="panel-start" display-mode="float">
        <calcite-action-bar slot="action-bar">
          <calcite-action
            data-action-id="legend"
            icon="legend"
            text="Legend"
          ></calcite-action>
        </calcite-action-bar>
        <calcite-panel
          heading="Legend"
          height-scale="l"
          data-panel-id="legend"
          hidden
        >
          <arcgis-legend
            id="legend-container"
            reference-element="#viewDiv"
          ></arcgis-legend>
        </calcite-panel>
      </calcite-shell-panel>
      <arcgis-map item-id="05e015c5f0314db9a487a9b46cb37eca" id="viewDiv" />
    </calcite-shell>
    <script type="module">
      // Reference the map component
      const mapElement = document.querySelector("arcgis-map");
      mapElement.addEventListener("viewReady", ({ detail: { view } }) => {
        view.ui.move("zoom", "top-right");
        view.padding = { left: 49 };
        let activeWidget;
        const handleActionBarClick = ({ target }) => {
          if (target.tagName !== "CALCITE-ACTION") {
            return;
          }
          const nextWidget = target.dataset.actionId;
          if (nextWidget === activeWidget) {
            target.active = false;
            document.querySelector(
              `[data-panel-id=${nextWidget}]`
            ).hidden = true;
            activeWidget = null;
          } else {
            if (activeWidget) {
              document.querySelector(
                `[data-action-id=${activeWidget}]`
              ).active = false;
              document.querySelector(
                `[data-panel-id=${activeWidget}]`
              ).hidden = true;
            }
            target.active = true;
            document.querySelector(
              `[data-panel-id=${nextWidget}]`
            ).hidden = false;
            activeWidget = nextWidget;
          }
        };
        let actionBarExpanded = false;
        document.addEventListener("calciteActionBarToggle", (event) => {
          actionBarExpanded = !actionBarExpanded;
          view.padding = {
            left: actionBarExpanded ? 150 : 49,
          };
        });
        document
          .querySelector("calcite-action-bar")
          .addEventListener("click", handleActionBarClick);
      });
    </script>
  </body>
</html>

 

RyukiHIRAMATSU_3-1708493276340.png

 

はじめてみよう!

コンポーネントのチュートリアルでは、最小限のコードで Web マッピング アプリケーションを構築するためのコンポーネントを見つけることができます。また、今後リリースされる追加コンポーネントにもご期待ください。

詳細については、コンポーネントのドキュメントを参照してください。問題が発生した場合は、トラブルシューティング ガイドを参照してください。また、他のユーザーとの共同作業、質問、問題の報告については、Esri コミュニティを参照してください。

 

参考情報:

Labels (1)
Version history
Last update:
‎02-20-2024 09:41 PM
Updated by:
Contributors