1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【初心者向け】ZENRIN Maps API でポリゴンを表示する

Last updated at Posted at 2025-08-05

はじめに

この記事では、ZENRIN Maps API の JavaScript API を使って、地図上にポリゴン(多角形)を表示する方法をご紹介します。
ポリゴンの描画は、施設やエリアの範囲を可視化したいときによく使われる基本機能のひとつです。
本記事では、APIの初学者の方にもわかりやすいように、地図の初期化からポリゴンの表示までをステップごとに、実際のコードとあわせて丁寧に解説していきます。
まずは簡単な表示からはじめて、応用への足がかりとしてお役立てください。

この記事でできること

  • ZENRIN Maps APIを使って地図を描画する
  • 地図上にポリゴンを表示する

公式リファレンス

本記事は、以下の公式リファレンスに基づいて作成しています。
詳細な仕様はこちらをご確認ください。


APIキーの取得方法

ZENRIN Maps API を利用するには、事前に APIキーの取得が必要です。

現在、ZENRIN Maps API は 2か月間の無料トライアルが用意されており、期間中は主要な機能を実際にお試しいただけます。開発や評価の初期段階でも安心してご利用いただけます。

APIキーの取得方法については、以下の記事で詳しく解説されています。
初めての方は、まずこちらをご覧いただき、APIキーの発行と設定を行ってください。

ZENRIN Maps APIの始め方

サンプル全体構成

以下の構成でファイルを準備してください。

project/
├── zma_polygon.html
└── js/
    └── zma_polygon.js

完成コードの全体

以下は、ZENRIN Maps APIで地図を表示し、ポリゴンを表示するサンプルコードです。
このコードはそのままコピー&ペーストで動作します(APIキーはご自身のものに置き換えてください)。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>ZENRIN Maps API - ポリゴン表示サンプル</title>
  <style>
    body {margin: 0; padding: 0;}
    #ZMap {position: absolute; top: 0; bottom: 0; width: 100%;}
    .control-panel {
      position: absolute;
      top: 10px;
      left: 10px;
      background: rgba(255, 255, 255, 0.9);
      padding: 10px;
      border-radius: 5px;
      box-shadow: 0 2px 5px rgba(0,0,0,0.2);
      z-index: 1000;
    }
    .control-panel button {
      margin: 2px;
      padding: 5px 10px;
      border: none;
      border-radius: 3px;
      background: #007bff;
      color: white;
      cursor: pointer;
    }
    .control-panel button:hover {
      background: #0056b3;
    }
  </style>
  <!--  APIキーを自身のものに変更してください -->
  <script src="https://test-js.zmaps-api.com/zma_loader.js?key=[APIキー]&auth=referer"></script>
</head>
<body>
  <div id="ZMap"></div>
  <div class="control-panel">
    <h4>ポリゴン操作</h4>
    <div id="status">地図を読み込み中...</div>
    <button id="simpleBtn" onclick="addSimplePolygon()" disabled>シンプルポリゴン</button>
    <button id="holeBtn" onclick="addPolygonWithHole()" disabled>穴あきポリゴン</button>
    <button id="clearBtn" onclick="clearPolygons()" disabled>クリア</button>
  </div>
  
  <script src="js/zma_polygon.js">
  </script>
</body>
</html>
zma_polygon.js
const lat = 35.681406, lng = 139.767132;
const mapElement = document.getElementById('ZMap');
let map;
let polygons = []; // ポリゴンを管理する配列

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

  mapOptions.center = new ZDC.LatLng(lat, lng);
  mapOptions.mouseWheelReverseZoom = true;
  mapOptions.zoom = 16; // ポリゴンが見やすいズームレベル

  map = new ZDC.Map(mapElement, mapOptions, function () {
    // 地図描画成功
    console.log('地図の初期化が完了しました');

    // コントロール追加
    map.addControl(new ZDC.ZoomButton('bottom-right', new ZDC.Point(-20, -35)));
    // 右上 コンパス
    map.addControl(new ZDC.Compass('top-right'));
    // 左下 スケールバー
    map.addControl(new ZDC.ScaleBar('bottom-left'));

    // ボタンを有効化
    document.getElementById('simpleBtn').disabled = false;
    document.getElementById('holeBtn').disabled = false;
    document.getElementById('clearBtn').disabled = false;
    document.getElementById('status').textContent = '地図の読み込み完了';

    // 地図が完全に読み込まれた後にポリゴンを追加
    setTimeout(() => {
      addSimplePolygon();
    }, 500);

  }, function () {
    console.error('地図の生成に失敗しました');
    document.getElementById('status').textContent = '地図の読み込みに失敗しました';
  });
});

// シンプルなポリゴンを追加
function addSimplePolygon() {
  if (!map) {
    console.error('地図が初期化されていません');
    return;
  }

  clearPolygons();

  // 頂点の配列を作成(東京駅周辺の四角形)
  const latlons = [];
  latlons.push(new ZDC.LatLng(35.6795, 139.7645)); // 左上
  latlons.push(new ZDC.LatLng(35.6835, 139.7695)); // 右上
  latlons.push(new ZDC.LatLng(35.6825, 139.7705)); // 右下
  latlons.push(new ZDC.LatLng(35.6785, 139.7655)); // 左下

  // ポリゴンを作成
  const polygon = new ZDC.Polygon(latlons, {
    fill: '#3498db',           // 青色の塗りつぶし
    fillPattern: 'solid',      // 塗りつぶしパターン
    stroke: '#2980b9',         // 枠線の色
    strokeWidth: 2,            // 枠線の太さ
    strokePattern: 'solid',    // 枠線のパターン
    opacity: 0.7               // 透明度
  });

  // ポリゴンを地図に追加
  map.addWidget(polygon);
  polygons.push(polygon);

  // クリックイベントを追加
  polygon.addEventListener('click', function(type, latLng, point) {
    alert('シンプルポリゴンがクリックされました!');
  });

  console.log('シンプルポリゴンを追加しました');
}

// 穴あきポリゴンを追加
function addPolygonWithHole() {
  if (!map) {
    console.error('地図が初期化されていません');
    return;
  }

  clearPolygons();

  // 外側の頂点配列を作成
  const outerPoints = [];
  outerPoints.push(new ZDC.LatLng(35.6760, 139.7620));
  outerPoints.push(new ZDC.LatLng(35.6860, 139.7650));
  outerPoints.push(new ZDC.LatLng(35.6870, 139.7730));
  outerPoints.push(new ZDC.LatLng(35.6820, 139.7750));
  outerPoints.push(new ZDC.LatLng(35.6750, 139.7720));
  outerPoints.push(new ZDC.LatLng(35.6740, 139.7640));

  // 内側(穴)の頂点配列を作成
  const innerPoints = [];
  innerPoints.push(new ZDC.LatLng(35.6810, 139.7680));
  innerPoints.push(new ZDC.LatLng(35.6830, 139.7690));
  innerPoints.push(new ZDC.LatLng(35.6820, 139.7710));
  innerPoints.push(new ZDC.LatLng(35.6800, 139.7700));

  // 穴あきポリゴンを作成(最初の配列が外側、2番目以降が穴)
  const polygonWithHole = new ZDC.Polygon([outerPoints, innerPoints], {
    fill: '#e74c3c',           // 赤色の塗りつぶし
    fillPattern: 'solid',      // 塗りつぶしパターン
    stroke: '#c0392b',         // 枠線の色
    strokeWidth: 3,            // 枠線の太さ
    strokePattern: 'solid',    // 枠線のパターン
    opacity: 0.6               // 透明度
  });

  // ポリゴンを地図に追加
  map.addWidget(polygonWithHole);
  polygons.push(polygonWithHole);

  // クリックイベントを追加
  polygonWithHole.addEventListener('click', function(type, latLng, point) {
    alert('穴あきポリゴンがクリックされました!');
  });

  console.log('穴あきポリゴンを追加しました');
}

// 全てのポリゴンをクリア
function clearPolygons() {
  if (!map) {
    return;
  }

  polygons.forEach(function(polygon) {
    try {
      map.removeWidget(polygon);
    } catch (e) {
      console.warn('ポリゴンの削除に失敗:', e);
    }
  });
  polygons = [];
  console.log('全てのポリゴンをクリアしました');
}

コードを実行した結果は、以下になります。
polygon_sample.png

コード解説(ステップごとに解説)

今回の実装では、ZENRIN Maps API を使って地図上に以下3つの操作ができる構成になっています:
・シンプルなポリゴンを表示する
・穴あきポリゴン(内側がくり抜かれた多角形)を表示する
・表示されたポリゴンをすべてクリアする
それでは、各処理について順を追って見ていきます。

Step 1:地図の初期化

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

  mapOptions.center = new ZDC.LatLng(lat, lng);
  mapOptions.mouseWheelReverseZoom = true;
  mapOptions.zoom = 16;

  map = new ZDC.Map(mapElement, mapOptions, function () {
    ...
  });
});
  • ZMALoader.setOnLoad は API 読み込み後に地図を初期化する関数です。
  • mapOptions.center に地図の中心座標(ここでは東京駅)を指定しています。
  • 地図が正常に読み込まれると、マップオブジェクトが生成され、コントロールやポリゴンの初期設定に進みます。

Step 2:地図コントロールの追加

map.addControl(new ZDC.ZoomButton('bottom-right', new ZDC.Point(-20, -35)));
map.addControl(new ZDC.Compass('top-right'));
map.addControl(new ZDC.ScaleBar('bottom-left'));
  • 地図上に ズームボタン, コンパス, スケールバー を追加しています。
  • ZDC.Point は表示位置のオフセットを指定するクラスです。

Step 3:ポリゴンボタンの有効化と自動描画

document.getElementById('simpleBtn').disabled = false;
document.getElementById('holeBtn').disabled = false;
document.getElementById('clearBtn').disabled = false;
document.getElementById('status').textContent = '地図の読み込み完了';

setTimeout(() => {
  addSimplePolygon();
}, 500);
  • 地図の読み込み完了後に、ボタンを有効化し、シンプルポリゴンを自動で一度描画します。
  • setTimeout() を使って描画タイミングを地図描画後に遅延させています。

Step 4:シンプルなポリゴンを追加する関数

function addSimplePolygon() {
  ...
  const latlons = [
    new ZDC.LatLng(35.6795, 139.7645),
    new ZDC.LatLng(35.6835, 139.7695),
    new ZDC.LatLng(35.6825, 139.7705),
    new ZDC.LatLng(35.6785, 139.7655)
  ];

  const polygon = new ZDC.Polygon(latlons, {
    fill: '#3498db',
    stroke: '#2980b9',
    strokeWidth: 2,
    opacity: 0.7
  });

  map.addWidget(polygon);
  polygon.addEventListener('click', function() {
    alert('シンプルポリゴンがクリックされました!');
  });
}
  • 四角形のようなポリゴンを表示します。
  • ZDC.Polygon の第1引数に 頂点の配列 を渡し、第2引数で色や線の設定を行います。
  • addEventListener でクリックイベントも設定可能です。

Step 5:穴あきポリゴン(複数の頂点配列を渡す)

function addPolygonWithHole() {
  ...
  const outerPoints = [...]; // 外枠
  const innerPoints = [...]; // 穴(内側)

  const polygonWithHole = new ZDC.Polygon([outerPoints, innerPoints], {
    fill: '#e74c3c',
    stroke: '#c0392b',
    strokeWidth: 3,
    opacity: 0.6
  });

  map.addWidget(polygonWithHole);
  polygonWithHole.addEventListener('click', function() {
    alert('穴あきポリゴンがクリックされました!');
  });
}
  • 複数のポリゴンパスを渡すことで「穴あきポリゴン」が作れます。
     ・最初の配列が外側の輪郭(外枠)
     ・2番目以降の配列が内側のくり抜き部分(穴)
  • ZDC.Polygon([[外枠], [穴1], [穴2], ...]) という構成になります。

Step 6:ポリゴンの削除処理

function clearPolygons() {
  polygons.forEach(function(polygon) {
    map.removeWidget(polygon);
  });
  polygons = [];
}
  • すでに表示しているポリゴンをすべて削除します。
  • 例外が発生してもアプリが落ちないよう、try-catch で安全に処理されています。

補足

  • polygons は表示中のポリゴンを管理するための配列で、必要な時に一括削除が可能です。
  • ボタン操作と紐づけているため、UIから簡単に操作できます。

よくある注意点

  • ポリゴンの座標は必ず ZDC.LatLng の形式で指定してください。
    頂点は new ZDC.LatLng(緯度, 経度) で生成し、配列にまとめて渡します。

  • 穴あきポリゴンを作成する場合は、外側・内側それぞれを配列で定義し、二次元配列として ZDC.Polygon に渡します。
    例:

    const polygon = new ZDC.Polygon([outerPoints, innerPoints], options);
    
  • 地図が表示されない場合は、以下の点を確認してください:
     ・ ZMALoader.setOnLoad() の使用方法が正しいか(関数参照を直接渡しているか)
     ・ APIキーが有効で、リファラー設定やIP制限に問題がないか
     ・ スクリプト読み込みURL(<script src="...">)が正しいか

  • APIキーには必ずセキュリティ設定を行ってください。 
     無制限で使える状態は不正利用のリスクがあります。

  • 地図が完全に読み込まれてから操作を行うようにしましょう。
     地図の初期化が完了する前にポリゴン追加処理などを呼び出すと、エラーになる場合があります。

  • クリックイベントを設定する際は、UI上の挙動にも配慮しましょう。
    今回のサンプルでは alert() を使っていますが、実運用では吹き出し表示や情報ウィンドウの活用が推奨されます。

おわりに

今回は ZENRIN Maps API を使って、地図上にポリゴンを描画する基本的な方法をご紹介しました。
少しずつ機能を試していくうちに、
「ポリゴンをクリックしたときに何か起きるようにしたい」
「複数のポリゴンをまとめて管理したい」
「外部データ(GeoJSON)から自動で描画したい」
といった応用にも自然と挑戦したくなるかもしれません。

そんなときは、ぜひ 公式リファレンス を参考にしながら、少しずつ実装の幅を広げてみてください。
この記事が、最初の一歩としてお役に立てれば嬉しいです。

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?