ドキュメントを検索

応用

ハウツー 住所で検索してその場所の地図を表示するには

「東京都千代田区大手町1-1-1」のような住所文字列から緯度経度を求めることをジオコーディングといいます。Geolonia Maps 自体はジオコーダを持っていないので、住所を扱うライブラリと組み合わせます。ここでは @geolonia/normalize-japanese-addresses(以下 NJA)を使います。

NJA はもともと住所の正規化をするライブラリです。表記のゆれを吸収して住所を整えたうえで、その地点の緯度経度も返してくれるので、そのまま地図に使えます。動きを確かめるだけなら公式のデモが手軽です。

返ってくるもの

normalize() は住所文字列を受け取り、分解した住所と位置情報を返します。

await normalize("東京都台東区上野公園7-7");
// {
//   pref: "東京都",
//   city: "台東区",
//   town: "上野公園",
//   addr: "7-7",
//   level: 8,
//   point: { lat: 35.714952981, lng: 139.775372778, level: 8 },
//   other: "",
//   metadata: { ... }
// }

levelpoint.level は別物です。 level は入力文字列をどこまで読み取れたか、point.level は返した座標がどれだけ細かい地点かを表します。

level読み取れた範囲point.level座標が指す場所
0都道府県も分からないpoint がありません)
1都道府県まで1都道府県庁の所在地
2市区町村まで2市区町村役場の所在地
3大字・丁目まで3大字・丁目の代表点
8街区符号・住居符号または地番まで8住居表示の位置、または地番の中央点

この2つは一致しないことがあります。番地まで読み取れても(level: 8)、その番地の位置情報が無ければ大字・丁目の代表点(point.level: 3)が返ります。

ズームは point.level に合わせてください

市区町村役場の座標にズーム 18 で寄ると、読み手には「その建物がその住所だ」と見えてしまいます。座標の細かさに応じてズームを変えるのが安全です。下のコードはどれもそうしています。

コード

住所を入力して検索すると、その場所へ地図が移動してマーカーが立ちます。

NJA は npm のパッケージですが、CDN から ES モジュールとして読み込めます。embed の CDN スクリプトは普通の <script>、NJA 側は <script type="module"> です。モジュールは後から実行されるので、geolonia は読み込み済みになっています。

<!doctype html>
<html>
  <head>
    <meta charset="UTF-8">
    <style>
      body { margin: 0; font: 14px/1.6 system-ui, sans-serif; }
      #wrap { display: flex; flex-direction: column; height: 100vh; }
      #search { display: flex; gap: 6px; padding: 8px; }
      #q { flex: 1; padding: 6px 8px; }
      #note { padding: 0 8px 8px; color: #555; }
      #map { flex: 1; }
    </style>
  </head>
  <body>
    <div id="wrap">
      <form id="search">
        <input id="q" aria-label="住所" value="東京都千代田区大手町1-1-1">
        <button type="submit">検索</button>
      </form>
      <div id="note">住所を入力して検索してください。</div>
      <div id="map" data-lat="35.68" data-lng="139.76" data-zoom="8" data-marker="off"></div>
    </div>

    <script src="https://cdn.geolonia.com/embed/v5/embed?geolonia-api-key=YOUR-API-KEY"></script>
    <script type="module">
      import { normalize } from "https://cdn.jsdelivr.net/npm/@geolonia/normalize-japanese-addresses@3.1.3/+esm";

      const ZOOM = { 1: 9, 2: 12, 3: 15, 8: 18 };

      const map = new geolonia.Map("#map");
      const marker = new geolonia.Marker();
      const note = document.getElementById("note");

      document.getElementById("search").addEventListener("submit", async (event) => {
        event.preventDefault();
        note.textContent = "検索中…";

        const result = await normalize(document.getElementById("q").value);
        if (!result.point) {
          marker.remove();
          note.textContent = "住所を特定できませんでした。";
          return;
        }

        const { lat, lng, level } = result.point;
        marker.setLngLat([lng, lat]).addTo(map);
        map.flyTo({ center: [lng, lat], zoom: ZOOM[level] });
        note.textContent =
          `${result.pref}${result.city}${result.town || ""}${result.addr || ""}` +
          `(位置情報レベル ${level})`;
      });
    </script>
  </body>
</html>
  • type="module":NJA を CDN から読むために必要です。バージョンは固定しておくと、更新で挙動が変わる事故を避けられます。
  • geolonia.Marker:embed を読み込むと window.geolonia に MapLibre GL JS の中身が入るので、マーカーやポップアップのクラスがそのまま使えます。
  • result.point の有無:住所を特定できなかったとき(level: 0)は point がありません。読む前に必ず確かめてください。

結果

上のコードは、それぞれのタブの下でそのまま動いています。初期値のまま検索すると大手町へ、東京都台東区上野公園7-7 に書き換えると番地の位置まで寄ります。

前者は 位置情報レベル 3、後者は 位置情報レベル 8 と出ます。同じ「番地まで書いた住所」でも、返る座標の細かさが違うことが確かめられます。

住所データの取得について

NJA は住所データを持ち歩かず、必要な範囲だけを Web API から都度取得します。既定の取得先は https://japanese-addresses-v2.geoloniamaps.com/api/ja です。

逆はできますか

緯度経度から住所を求める(逆ジオコーディング)ことは、NJA ではできません。NJA は住所文字列を入力に取るライブラリです。

うまくいかないとき

うまくいかないとき
  • 何も起きない → result.point が無い場合を処理しているか確認してください。住所を特定できなかったときは level: 0point が付きません。
  • 建物名を入れると精度が落ちる → 末尾の建物名は other に残るだけで座標には効きませんが、住所の読み取り自体を邪魔することがあります。あらかじめ分けておくのが確実です。
  • 番地まで入れたのに大まかな場所しか出ない → その番地の位置情報が無く、大字・丁目の代表点が返っています。point.level を見れば区別できます。
  • 検索のたびにマーカーが増える → マーカーを毎回作っています。1つ作って位置を付け替えてください。

関連:全地点が画面に収まるように表示するにはクリックでポップアップを出すには