メインコンテンツまでスキップ

【JavaScript】ArcGISで動的にMapViewを配置する

· 約4分
ogumaru

概要

ArcGIS API for JavaScript (@arcgis/core)で MapView を利用する際、インスタンス化時に container プロパティにセレクタの文字列かHTMLElementを指定することで、そこに地図を表示することができる。

React を利用する都合上、静的な HTML ではなく、表示対象となる要素(React コンポーネント)が描画されたあと、そこに表示されるようにしたい。

実装は ES Modules および TypeScript を利用して行った。

結論

useEffect内で__esri.Accessor.set()からcontainerを指定する。

import { useEffect } from "react";
import MapView from "@arcgis/core/views/MapView";

// ここでは container は指定しない。
// レイヤの操作をする都合上、
// export する必要があるためsetup内でインスタンス化できない。
export const mapView = new MapView({
/** 略 **/
});

const setup = () => {
// 動的に container を指定
mapView.set("container", "viewDiv");
};

export const App = () => {
useEffect(setup, []);
return (
<>
<div id="viewDiv"></div>
</>
);
};

環境

項目内容
React18.2.0
ArcGIS API for JavaScript4.24.7
TypeScript4.8.4
webpack5.74.0

動的な配置

MapViewがインスタンス化されたときにcontainerに指定した際、この時点で該当の HTML 要素がない場合は地図が表示されない。

React を利用している場合、コンポーネントがマウントされたタイミングで描画されるように、useEffect内でMapViewをインスタンス化すれば問題なく表示ができる。

containerプロパティ

サンプルコードなどでは下記のようにコンストラクタでcontainerに HTML 要素のid文字列を指定することが多い。

const mapView = new MapView({
// (略)
container: "viewDiv",
});

このとき、containerプロパティの型は string | HTMLDivElementとなっているため、TypeScript の型エラーは出ない。

(ヒントには__esri.DOMContainerProperties.container?: string | HTMLDivElementとでるが、該当の型はドキュメントには見つからなかった)

MapView | API Reference | ArcGIS API for JavaScript 4.24 | ArcGIS Developers - (developers.arcgis.com)

一方、MapViewがインスタンス化された場合、containerプロパティはDOMContainer.containerを指してしまい、指定できるのはHTMLDivElementのみとなる。

DOMContainer | API Reference | ArcGIS API for JavaScript 4.24 | ArcGIS Developers - (developers.arcgis.com)

そのため下記コードでは型エラーが発生してしまう。

const mapView = new MapView(...);
mapView.container = "viewDiv"

Type 'string' is not assignable to type 'HTMLDivElement'.ts(2322)

MapViewではなく、これが継承している__esri.Accessorsetメソッドを持っており、これを利用することで動的にcontainerを指定することができた。

Accessor | API Reference | ArcGIS API for JavaScript 4.24 | ArcGIS Developers - (developers.arcgis.com)