3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

住所検索の正確さを比較!Google Maps APIとZENRIN Maps API

Last updated at Posted at 2025-02-13

はじめに

本記事の目的
記事の目的と背景を説明します。日本の住所は多様で、特に難読住所が存在します。
このような住所をどのように正確に検索できるかを比較します。

日本の住所システムの複雑さ

日本の住所システムは、住居表示と地番の併存や京都の通り名など、地域ごとに異なる特徴があります。
これらの特徴を考慮した住所検索は非常に重要です。
例: 京都の通り名
京都では、通り名を用いた住所表記が一般的です。
例えば、「御池通河原町東入一之船入町」など、地元の人には分かりやすいですが、外の人には難しいです。
例: 表記ゆれと省略記法
日本の住所では、表記ゆれや省略記法が多く見られます。例えば、「1丁目」と「1-」や「1の」などの表記の違いがあります。

APIキーの取得

Google Maps Platform

1.下記のページに接続します。
Google Cloud Platform
2.「APIとサービス」メニューをクリックする。
GMP_1.png
3.「認証情報」リンクをクリックして、「認証情報を作成」メニューから「APIキー」を選択します。
GMP_2.png
4.この時点でAPIキーは作成されますが、セキュリティの強化のため「キーを制限」設定を行ってください。
GMP_3.png
5.キーを利用するAPIに適したキーの制限を行います。
キーの制限を行わずにAPIキーを利用した場合、外部にキー情報が洩れると悪意のあるユーザに利用されてしまう恐れがあるのでご注意下さい。
下記から適切な制限を選択して設定を保存して下さい。
GMP_4.png

項目
HTTPリファラー(ウェブサイト) HTTPリファラーによる制限
IPアドレス(ウェブサーバー、crronジョブなど) IPアドレスによる制限
Androidアプリ パッケージ名およびフィンガープリントによる制限
iOSアプリ iOSハンドル識別子による制限

ZENRIN Maps API
1.検証用IDとパスワード(PW)取得
ZENRIN Maps APIを使用するためには、検証用IDとPWを取得しなければなりません。
お試しIDは下記からで簡単に発行できました。

1-1.検証用IDとPWの発行を依頼
以下の、URLから必要事項を入力して送信します。
ZENRIN Maps API 無料お試しID お申込みフォーム(2か月無料でお試しできます)

ZMA_1.png

1-2.検証用IDとPWの確認
フォーム送信から3営業日以内にメールにて検証用IDとPWが発行されます。

2.コンソールにログイン
以下のURLでメールにて送られてきたIDとPWを入力し、ログインをします。
ZMA_2.png

3.ユーザーの設定
ユーザー設定にて、「コンソール管理者メールアドレス」と「情報配信用メールアドレス」を設定します。
特にコンソール管理者メールアドレスはZENRIN Maps API コンソールのパスワードを忘れて再設定が必要となった場合に必要になります。
ZMA_3.png

4.チャネルの認証方式の設定、チャネル名変更
チャネルの設定変更は左メニューの「チャネル設定」から行うことができます。
「チャネル設定」押下後表示される画面にはチャネルの一覧が表示されています。
設定を行うチャネルの「編集」ボタンを押下してください。
ZMA_4.png

認証方式は3種類あり、設定したいタブを押下するとそれぞれの認証方式の設定項目が表示されます。
認証方式を有効にするには、「無効」を「有効」に変更してください。
有効にしたい認証方式が複数ある場合は、それぞれの認証方式のタブで「有効」状態に変更してください。
それぞれの設定項目を入力後「変更」ボタンを押下すると有効状態と設定項目が反映されます。
ZMA_5.png

5.APIキーの取得・API利用開始
「チャネル一覧」のグレーアウトされている箇所にマウスオーバーすると表示される「APIキー」を使い、
下記URLのAPIリファレンス に則りAPIの利用を開始してください。
リファレンス

これで準備は完了です。
ZMA_6.png

サンプルコード

Google Maps Platform

gmp_address_search.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Google Maps 住所検索</title>
    <script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"></script>
    <style>
        #map {
            width: 100%;
            height: 400px;
            margin-top: 10px;
        }
    </style>
</head>
<body>
    <h2>Google Maps 住所検索</h2>
    <input type="text" id="address" placeholder="住所を入力してください">
    <button onclick="searchAddress()">検索</button>
    <div id="map"></div>

    <script>
        let map, geocoder, marker, infoWindow;

        function initMap() {
            // 初期位置(東京)
            const defaultLocation = { lat: 35.682839, lng: 139.759455 };
            
            map = new google.maps.Map(document.getElementById("map"), {
                zoom: 15,
                center: defaultLocation
            });

            geocoder = new google.maps.Geocoder();
            marker = new google.maps.Marker({
                map: map,
                position: defaultLocation
            });

            infoWindow = new google.maps.InfoWindow();
        }

        function searchAddress() {
            const address = document.getElementById("address").value;

            if (!address) {
                alert("住所を入力してください");
                return;
            }

            geocoder.geocode({ address: address }, function(results, status) {
                if (status === "OK") {
                    const location = results[0].geometry.location;
                    const formattedAddress = results[0].formatted_address;
                    const addressReading = extractAddressReading(results[0].address_components);

                    map.setCenter(location);
                    marker.setPosition(location);

                    // 情報ウィンドウに住所、読み、緯度経度を表示
                    const contentString = `
                        <div>
                            <strong>住所:</strong> ${formattedAddress}<br>
                            <strong>住所の読み:</strong> ${addressReading || "不明"}<br>
                            <strong>緯度:</strong> ${location.lat().toFixed(6)}<br>
                            <strong>経度:</strong> ${location.lng().toFixed(6)}
                        </div>
                    `;

                    infoWindow.setContent(contentString);
                    infoWindow.open(map, marker);

                    console.log("住所:", formattedAddress);
                    console.log("住所の読み:", addressReading || "不明");
                    console.log("緯度:", location.lat(), "経度:", location.lng());
                } else {
                    alert("住所が見つかりませんでした: " + status);
                }
            });
        }

        function extractAddressReading(addressComponents) {
            for (let component of addressComponents) {
                if (component.types.includes("political") || component.types.includes("sublocality") || component.types.includes("locality")) {
                    if (component.long_name && component.short_name) {
                        return component.short_name; // ふりがな情報(省略形がふりがなの可能性あり)
                    }
                }
            }
            return null;
        }
    </script>
</body>
</html>

ZENRIN Maps API

zma_address_search.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Display a map</title>
  <style>
    body { margin: 0; padding: 0; font-family: Arial, sans-serif; }
    
    #search-bar {
      position: absolute;
      top: 10px;
      left: 10px;
      background-color: #fff;
      padding: 10px;
      border-radius: 5px;
      box-shadow: 0 0 10px rgba(0,0,0,0.2);
      z-index: 1;
    }

    #result {
      position: absolute;
      top: 70px;
      left: 10px;
      background-color: rgba(255, 255, 255, 0.9);
      padding: 10px;
      border-radius: 5px;
      box-shadow: 0 0 10px rgba(0,0,0,0.2);
      z-index: 1;
      display: none;
    }

    #ZMap {
      position: absolute;
      top: 0;
      bottom: 0;
      width: 100%;
    }
  </style>
  
  <!-- ローダーを読み込む -->
  <script src="https://test-js.zmaps-api.com/zma_loader.js?key=YOUR_API_KEY&auth=referer"></script>
</head>
<body>
  <div id="search-bar">
    <input type="text" id="address" placeholder="住所を入力してください">
    <button onclick="searchAddress()">検索</button>
  </div>

  <!-- 検索結果の表示エリア -->
  <div id="result">
    <p><strong>検索結果:</strong></p>
    <p>住所: <span id="result-address">-</span></p>
    <p>住所読み: <span id="result-address_read">-</span></p> 
    <p>緯度: <span id="result-lat">-</span></p>
    <p>経度: <span id="result-lng">-</span></p>
  </div>

  <div id="ZMap"></div>

  <script src="js/zma_addressmatch3.js"></script>
</body>
</html>
zma_address_search.js
// グローバル変数として `map` と `mrk_widget` を定義
let map;
let mrk_widget;

// ローダーのメソッド実行
ZMALoader.setOnLoad(function (mapOptions, error) {
  if (error) {
    console.error(error)
    return
  }

  // 地図オブジェクト
//  var map;

  // 中心点の緯度経度(東京駅)
  const lat = 35.681406, lng = 139.767132;

  // マップコンテナ要素を取得する
  const mapElement = document.getElementById('ZMap');

  // MapOptionsをデフォルト値から変更する場合各パラメータに値を設定
  // 中心点の緯度経度を設定
  mapOptions.center = new ZDC.LatLng(lat, lng);
  mapOptions.zipsMapType = 'VeAmBrmV'
  mapOptions.mouseWheelReverseZoom = true; // ★マウスホイールのズーム方向の反転を指定


  // 地図を生成
  map = new ZDC.Map(
    mapElement,
    mapOptions,
    function() {
      // Success callback
      // コントロールを追加する
      // 左上 拡大縮小ボタン表示
      map.addControl(new ZDC.ZoomButton('bottom-right'));
      // 右上 コンパス表示
      map.addControl(new ZDC.Compass('top-right'));
      // 左下 スケールバー表示
      map.addControl(new ZDC.ScaleBar('bottom-left'));

    },
    function() {
      // Failure callback
    }
  );
})

async function searchAddress() {
  const address = document.getElementById("address").value;

  if (!address) {
      alert("住所を入力してください");
      return;
  }

  try {
      const response = await fetch('https://test-web.zmaps-api.com/search/address', {
          method: 'POST',
          headers: {
              'Content-Type': 'application/x-www-form-urlencoded',
              'x-api-key': 'YOUR_API_KEY',
              'Authorization': 'referer'
          },
          body: new URLSearchParams({
              word: address,
              word_match_type: '3'
          })
      });

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      const data = await response.json();
      console.log(data.result.item);

        if (data.status === "OK" && data.result.info.hit > 0) {
            const location = data.result.item[0].position;
              
              // 配列の順序が[経度, 緯度]であることを確認
              const lng = location[0];
              const lat = location[1];

              const latLng = new ZDC.LatLng(lat, lng);

              // 地図をその位置に移動
              map.setCenter(latLng);

              /* Markerの設置 */
              center_mrk =new ZDC.CenterMarker();
              // MarkerをMapに追加
              map.addControl(center_mrk);

              // 検索結果を表示
              document.getElementById("result-address").textContent = data.result.item[0].address;
              document.getElementById("result-address_read").textContent = data.result.item[0].address_read;
              document.getElementById("result-lat").textContent = lat;
              document.getElementById("result-lng").textContent = lng;
              document.getElementById("result").style.display = "block";

              console.log("緯度:", lat, "経度:", lng);
          } else {
              alert("住所の位置情報が見つかりませんでした");
          }
      }  catch (error) {
      console.error("エラーが発生しました:", error);
      alert("住所の検索中にエラーが発生しました");
  }
}

地図表示

Google Maps Platform
GMP_address.png
ZENRIN Maps API
ZENRINMapsAPI 住所検索
ZMA_address.png

解説

Google Maps Platform

1.HTML構造とスタイル

この部分では、基本的なHTML構造を定義しています。
<head>タグ内で、Google Maps APIのスクリプトを読み込み、callbackとしてinitMap関数を指定しています。

gmp_address_search.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Google Maps 住所検索</title>
    <script async defer src="https://maps.googleapis.com/maps/api/js?key=&callback=initMap"></script>
    <style>
        #map {
            width: 100%;
            height: 400px;
            margin-top: 10px;
        }
    </style>
</head>
<body>
    <h2>Google Maps 住所検索</h2>
    <input type="text" id="address" placeholder="住所を入力してください">
    <button onclick="searchAddress()">検索</button>
    <div id="map"></div>

スタイル: CSSスタイルで、地図を表示する#map要素の幅と高さを設定しています。
入力フォーム: 住所を入力するためのテキストボックスと検索ボタンを提供しています。

2.初期化関数 initMap()

function initMap() {
    const defaultLocation = { lat: 35.682839, lng: 139.759455 };
    
    map = new google.maps.Map(document.getElementById("map"), {
        zoom: 15,
        center: defaultLocation
    });

    geocoder = new google.maps.Geocoder();
    marker = new google.maps.Marker({
        map: map,
        position: defaultLocation
    });

    infoWindow = new google.maps.InfoWindow();
}

地図の初期化: initMap関数は、Google Maps APIが読み込まれた後に自動的に実行されます。地図を東京の位置に初期化し、ズームレベルを15に設定します。
マーカーと情報ウィンドウの設定: 地図上にマーカーを表示し、情報ウィンドウを準備します。

3.住所検索関数 searchAddress()

function searchAddress() {
    const address = document.getElementById("address").value;

    if (!address) {
        alert("住所を入力してください");
        return;
    }

    geocoder.geocode({ address: address }, function(results, status) {
        if (status === "OK") {
            const location = results[0].geometry.location;
            const formattedAddress = results[0].formatted_address;
            const addressReading = extractAddressReading(results[0].address_components);

            map.setCenter(location);
            marker.setPosition(location);

            const contentString = `
                <div>
                    <strong>住所:</strong> ${formattedAddress}<br>
                    <strong>住所の読み:</strong> ${addressReading || "不明"}<br>
                    <strong>緯度:</strong> ${location.lat().toFixed(6)}<br>
                    <strong>経度:</strong> ${location.lng().toFixed(6)}
                </div>
            `;

            infoWindow.setContent(contentString);
            infoWindow.open(map, marker);

            console.log("住所:", formattedAddress);
            console.log("住所の読み:", addressReading || "不明");
            console.log("緯度:", location.lat(), "経度:", location.lng());
        } else {
            alert("住所が見つかりませんでした: " + status);
        }
    });
}

住所入力のチェック: 住所が入力されていない場合、警告メッセージを表示します。
住所のジオコーディング: 入力された住所をジオコーディングして、緯度経度を取得します。
地図の更新: 地図の中心を検索結果の位置に移動し、マーカーを更新します。
情報ウィンドウの表示: 情報ウィンドウに住所、読み、緯度経度を表示します。

4.住所読み取り関数 extractAddressReading()

function extractAddressReading(addressComponents) {
    for (let component of addressComponents) {
        if (component.types.includes("political") || component.types.includes("sublocality") || component.types.includes("locality")) {
            if (component.long_name && component.short_name) {
                return component.short_name; // ふりがな情報(省略形がふりがなの可能性あり)
            }
        }
    }
    return null;
}

住所読み取りの抽出: 住所のコンポーネントから、政治的または地域的な要素を探し、その短縮名(ふりがな情報として使用)を返します。

ZENRIN Maps API

1.地図の初期化

zma_address_search.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Display a map</title>
    <style>
        /* スタイル設定 */
        body { margin: 0; padding: 0; font-family: Arial, sans-serif; }
        
        #search-bar {
          position: absolute;
          top: 10px;
          left: 10px;
          background-color: #fff;
          padding: 10px;
          border-radius: 5px;
          box-shadow: 0 0 10px rgba(0,0,0,0.2);
          z-index: 1;
        }

        #result {
          position: absolute;
          top: 70px;
          left: 10px;
          background-color: rgba(255, 255, 255, 0.9);
          padding: 10px;
          border-radius: 5px;
          box-shadow: 0 0 10px rgba(0,0,0,0.2);
          z-index: 1;
          display: none;
        }

        #ZMap {
          position: absolute;
          top: 0;
          bottom: 0;
          width: 100%;
        }
    </style>
    
    <!-- ローダーを読み込む -->
    <script src="https://test-js.zmaps-api.com/zma_loader.js?key=YOUR_API_KEY&auth=referer"></script>
</head>
<body>
    <div id="search-bar">
        <input type="text" id="address" placeholder="住所を入力してください">
        <button onclick="searchAddress()">検索</button>
    </div>

    <!-- 検索結果の表示エリア -->
    <div id="result">
        <p><strong>検索結果:</strong></p>
        <p>住所: <span id="result-address">-</span></p>
        <p>住所読み: <span id="result-address_read">-</span></p>    
        <p>緯度: <span id="result-lat">-</span></p>
        <p>経度: <span id="result-lng">-</span></p>
    </div>

    <div id="ZMap"></div>

    <script src="js/zma_address_search.js"></script>
</body>
</html>

基本構造: HTML文書の基本的な構造を定義しています。
スタイル設定: CSSスタイルで、検索バー、結果表示エリア、地図のレイアウトを設定しています。
ローダーの読み込み: ZENRIN Maps APIのローダーを読み込みます。

2.初期関数

zma_address_search.js
ZMALoader.setOnLoad(function (mapOptions, error) {
   if (error) {
       console.error(error)
       return
   }

   // 地図オブジェクト
   const lat = 35.681406, lng = 139.767132;
   const mapElement = document.getElementById('ZMap');

   // MapOptionsを設定
   mapOptions.center = new ZDC.LatLng(lat, lng);
   mapOptions.zipsMapType = 'VeAmBrmV'
   mapOptions.mouseWheelReverseZoom = true;

   // 地図を生成
   map = new ZDC.Map(
       mapElement,
       mapOptions,
       function() {
           // Success callback
           map.addControl(new ZDC.ZoomButton('bottom-right'));
           map.addControl(new ZDC.Compass('top-right'));
           map.addControl(new ZDC.ScaleBar('bottom-left'));
       },
       function() {
           // Failure callback
       }
   );
})

地図の初期化: 東京駅を中心に地図を初期化し、ズームボタンやコンパスなどのコントロールを追加します。

3.住所検索関数 searchAddress()

zma_address_search.js
async function searchAddress() {
   const address = document.getElementById("address").value;

   if (!address) {
       alert("住所を入力してください");
       return;
   }

   try {
       const response = await fetch('https://test-web.zmaps-api.com/search/address', {
           method: 'POST',
           headers: {
               'Content-Type': 'application/x-www-form-urlencoded',
               'x-api-key': 'YOUR_API_KEY',
               'Authorization': 'referer'
           },
           body: new URLSearchParams({
               word: address,
               word_match_type: '3'
           })
       });

       if (!response.ok) {
           throw new Error(`HTTP error! status: ${response.status}`);
       }

       const data = await response.json();
       console.log(data.result.item);

       if (data.status === "OK" && data.result.info.hit > 0) {
           const location = data.result.item[0].position;
           const lng = location[0];
           const lat = location[1];

           const latLng = new ZDC.LatLng(lat, lng);

           // 地図をその位置に移動
           map.setCenter(latLng);

           /* Markerの設置 */
           center_mrk = new ZDC.CenterMarker();
           map.addControl(center_mrk);

           // 検索結果を表示
           document.getElementById("result-address").textContent = data.result.item[0].address;
           document.getElementById("result-address_read").textContent = data.result.item[0].address_read;
           document.getElementById("result-lat").textContent = lat;
           document.getElementById("result-lng").textContent = lng;
           document.getElementById("result").style.display = "block";

           console.log("緯度:", lat, "経度:", lng);
       } else {
           alert("住所の位置情報が見つかりませんでした");
       }
   } catch (error) {
       console.error("エラーが発生しました:", error);
       alert("住所の検索中にエラーが発生しました");
   }
}

住所入力のチェック: 住所が入力されていない場合、アラートを表示します。
住所検索APIの呼び出し: ZENRIN Maps APIの住所検索APIを使用して、入力された住所の位置情報を取得します。
地図の更新と結果表示: 検索結果に基づいて地図を更新し、住所や緯度経度を表示します。

難読住所の検索比較

1. 埼玉県蕨市

Google Maps Platform
gmp_address_warabi.png
ZENRIN Maps API
ZMA_address_warabi.png

2. 千葉県匝瑳市

Google Maps Platform
gmp_address_sousa.png
ZENRIN Maps API
ZMA_address_sousa.png

3. 石川県羽咋市

Google Maps Platform
gmp_address_hakui.png
ZENRIN Maps API
ZMA_address_hakui.png

主な結論

住所の読み方の正確さ
ZENRIN Maps APIは、市区町村名だけでなく、町名や丁目名の読み方も正確に取得できました。
一方、Google Maps APIは市区町村名のみを返却し、町名や丁目名の読み方は取得できませんでした。
地名の正確さ
ZENRIN Maps APIは、日本国内の地図データの精度が高く、特に新しい地域や施設情報の反映が迅速です。これにより、不動産や物流業界での利用に適しています。
カスタマイズ性と拡張性
ZENRIN Maps APIは、カスタマイズ性が高く、日本国内特有の道路事情や規制に対応した詳細な設定が可能です。

推奨

ZENRIN Maps API: 日本国内向けの高精度な地図データとカスタマイズ性が求められるプロジェクトに最適です。特に、不動産や物流業界での利用が推奨されます。
Google Maps API: グローバルな展開が必要なプロジェクトや、シンプルな実装が求められる場合に適しています。
これらの特徴を考慮して、プロジェクトの目的や地域に応じたAPIの選択が重要です。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?