https://community.esri.com/people/EPolle_TensingInternational/blog/2020/03/24/arcgis-javascript-with-uk-data-table-of-content
マップビューを保持するために URL に x, y とズームレベルを設定する方法
地図上の特定の場所をズームインするとき、そのマップビューを保持しておきたい、例えば誰かと共有したいと思うことがあります。そこで、URL の検索パラメータから x, y とズームレベルを取得する方法を探していました。しかし、クエリ文字列(つまり疑問符の後ろのすべて)から値を読み取るだけでなく、それらを設定し、マップビューが変わるたびに(ユーザーが地図上でパンやズームを行うときに)それらを変更できるようにしたいのです。
以下は、x と y 座標(British National Grid で、メートル単位で丸めています)を取得し、URL を変更する機能の説明です。<\/SPAN>
URLSearchParams と History.replaceState()
URLSearchParams インターフェースは URL のクエリ文字列を操作するためのユーティリティメソッドを定義しています。以下の例では、このインターフェースの次のメソッドを使用しています:
- has() メソッドは指定された名前のパラメータが存在するかどうかを示します
- get() メソッドは指定された検索パラメータに関連付けられた(最初の)値を返します
- set() メソッドは指定された検索パラメータに関連付けられた値を設定します。非常に重要なのは、検索パラメータがまだ存在しない場合(最初はそうかもしれません)、このメソッドが検索パラメータを作成することです。
History.replaceState() メソッドは現在の履歴エントリを変更します。このメソッドは、前述のパンやズームなどユーザーアクションに応じて現在の履歴エントリの URL を更新したい場合に特に便利です。
動作の仕組み:
パラメータなしの URL を提供すると、デフォルトのマップビューから開始します。しかしご覧の通り、デフォルトパラメータがすぐにアドレスバーに追加されます:
https://twiav.nl/en/arcgis/javascript/arcgis_javascript_with_uk_data_url_parameters.htm
そしてズームやパンを始めると、ビューが「静止」状態になるたびにこれらのパラメータが調整されます(reactiveUtils を使ってビューの状態が静止かどうかチェックしています)。
このようにして特定の場所にズームインし、その URL をコピーして正確なマップビューを共有できます。
下記リンクをクリックするとすぐに Steòrnabhagh (英語では Stornoway、ここでは Web Map GB Cartographic Local Names を使用)にある Outer Hebrides の Lewis and Harris 島へ移動します:
https://twiav.nl/en/arcgis/javascript/arcgis_javascript_with_uk_data_url_parameters.htm?x=143956&y=932940&l=12
楽しいコーディングを!
コード
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
<title>ArcGIS JavaScript と UK データ - URL パラメータ: x, y とズームレベル</title>
<link rel="stylesheet" href="https://js.arcgis.com/4.29/esri/css/main.css">
<script src="https://js.arcgis.com/4.29/"></script>
<style>
html, body, #viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<script>
require([
"esri/Map",
"esri/geometry/Point",
"esri/views/MapView",
"esri/widgets/Home",
"esri/Viewpoint",
"esri/core/reactiveUtils"
], function(Map, Point, MapView, Home, Viewpoint, reactiveUtils) {
var sr = 27700;
var xCoordHome = 500000;
var yCoordHome = 500000;
var zoomLevelHome = 5;
var scaleHome = 4612360;
var xCoord = xCoordHome;
var yCoord = yCoordHome;
var zoomLevel = zoomLevelHome;
if ('URLSearchParams' in window) { // 機能検出 (Internet Explorer は URLSearchParams をサポートしていません)
var url = new URL(document.URL);
var search_params = url.searchParams;
// URL に x, y, l があれば取得
if(search_params.has('x') && search_params.has('y') && search_params.has('l')) {
var xCoord = parseInt(search_params.get('x'));
var yCoord = parseInt(search_params.get('y'));
var zoomLevel = parseInt(search_params.get('l'));
}
};
var map = new Map({
basemap: {
portalItem: {
id: "5b9d5ac7e17f402a9111f1ca2c22bf56"
// GB Cartographic Local Names, EsriUKContent がホストしています。詳細:https://www.arcgis.com/home/item.html?id=5b9d5ac7e17f402a9111f1ca2c22bf56
}
}
});
var view = new MapView({
spatialReference: sr,
container: "viewDiv",
map: map,
center: new Point({x: xCoord, y: yCoord, spatialReference: sr}),
zoom: zoomLevel
});
var home = new Home({
view: view,
// home の viewpoint は定義が必要(ハードコード)です。さもないと home は検索パラメータ内の x, y, l に依存します。
viewpoint: new Viewpoint({targetGeometry: new Point({x: xCoordHome, y: yCoordHome, spatialReference: sr}), scale: scaleHome})
});
view.ui.add(home, "top-left")
reactiveUtils.when(
() => view?.stationary === true,
() => {
modifySearchParams();
});
// 新しい座標とズームレベルで検索パラメータとして URL を変更
function modifySearchParams() {
if ('URLSearchParams' in window) { // 機能検出 (Internet Explorer は URLSearchParams をサポートしていません)
xCoordNew = parseInt(view.center.x);
yCoordNew = parseInt(view.center.y);
zoomLevelNew = view.zoom;
search_params.set('x', xCoordNew);
search_params.set('y', yCoordNew);
search_params.set('l', zoomLevelNew);
url.search = search_params.toString(); // メイン URL の search プロパティを変更
new_url = url.toString(); // 新しい URL 文字列
history.replaceState(null, '', new_url);
}
}
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>