はじめに
TerraMap APIから「小学校区・中学校区データ」を取得できるようになりましたので、その使用例をサンプルコードと一緒にご紹介したいと思います。
TerraMap APIが提供する「小学校区・中学校区データ」は国土数値情報で公開されている学校区データと異なり、99%以上の市区町村をカバーし、各市区町村で異なる利用条件への対応は必要ありません。
完成イメージ
Google Mapの地図上をクリックし、その地点の小学校区ポリゴンをGeoJSON形式で取得、ポリゴンと学校位置を表示させるアプリケーションを作成しました。
国土数値情報では提供されていない東京都品川区の小学校区を表示した例
小学校区・中学校区データについて
TerraMap APIの「小学校区・中学校区データ」は、学区ポリゴンと各属性値で構成されています。主な用途や特徴は、以下が考えられます。
学校区データの主な用途
- 教育関連施設の位置計画
- 物件データに対する学区判定
- 販促・広告計画
学校区データの特徴(国土数値情報との比較)
国土数値情報の学校区データより多くの市区町村、小学校、中学校に対応しています。また、市区町村ごとに分かれる利用条件への対応も必要ありません。
項目 | TerraMap API | 国土数値情報 |
---|---|---|
ライセンス | 商用利用可 | 一部商用利用不可 |
市区町村カバー率 | 99%以上 (約1,700 市区町村) |
約87% (約1,500 市区町村) |
更新頻度 | 毎年 | 数年に1度 |
TerraMap API とは、多数のエリアマーケティングデータ(統計データ、ポリゴン、住所)を提供する地図システム開発支援APIです。詳しくは以下のリンク先をご参照下さい。
フロントエンド
フロントエンドでは、以下のようなフローを実現させました。
地図上のクリック → サーバーへのリクエスト(緯度・経度を渡す)
→ 小学校区ポリゴンの取得と表示 → 学校位置のマーカー表示
HTML
Google Mapを表示するには、YOUR_GOOGLE_MAP_KEY
部分にGoogle Maps Platform用のAPIキーが必要となります。この記事では「APIキーを使用する」等の手順は割愛させていただきます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>小学校区ポリゴンを取得し、Google Mapに表示する</title>
<link rel="stylesheet" type="text/css" href="./style.css" />
<script type="module" src="./index.js"></script>
</head>
<body>
<div id="map" style="width: 97vw; height: 97vh"></div>
<!-- prettier-ignore -->
<script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
({key: "YOUR_GOOGLE_MAP_KEY", v: "weekly"});</script>
</body>
</html>
小学校区ポリゴン表示
地図のクリックイベントで、小学校区ポリゴンを取得し表示する処理は以下のようになります。
// 地図クリックイベント
map.addListener("click", (event) => {
const { latLng } = event;
const lat = latLng.lat();
const lng = latLng.lng();
// クリックした位置の小学校区ポリゴンを取得
fetch(`http://127.0.0.1:3000/get-gakku-polygon`, { // サーバーURLは適宜変更してください
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ lat, lng }),
})
.then((response) => response.json())
.then((data) => {
// GeoJSONデータを地図に追加
map.data.addGeoJson(data);
})
.catch((error) => {
console.log(error);
});
});
// ポリゴンのスタイル設定
const polygonStyleOptions = {
strokeColor: "#810FCB",
strokeOpacity: 1.0,
strokeWeight: 2.0,
fillColor: "#810FCB",
fillOpacity: 0.5,
};
// 地図上のマルチポリゴンにスタイルを適用
map.data.setStyle((feature) => {
if (feature.getGeometry().getType() === "MultiPolygon") {
return polygonStyleOptions;
}
return null;
});
学校位置のマーカー表示
マーカー表示については現在推奨されている 高度なマーカー を用いて実現しています。AdvancedMarkerElement
と PinElement
を読み込み、地図には マップID が必要になります。
async function initMap() {
const { Map } = await google.maps.importLibrary("maps");
const { AdvancedMarkerElement, PinElement } = await google.maps.importLibrary("marker");
const centerLocation = { lat: 35.681095, lng: 139.686144 };
const map = new Map(document.getElementById("map"), {
zoom: 14,
center: centerLocation,
mapId: "DEMO_MAP_ID", // デモ用マップID。本番環境では適切なマップIDに変更してください。
});
// 以降省略
小学校区ポリゴンに含まれる小学校位置と小学校名を読み取り、マーカーを地図に追加するには、 map.data.addGeoJson(data);
の後に以下を記述します。
今回はマーカーラベルにdiv要素を用いているので、CSSによるスタイル設定も可能になります。
// 小学校の位置
const schoolPosition = {
lat: data.features[0].properties.point_coordinates[1],
lng: data.features[0].properties.point_coordinates[0],
};
// マーカーラベルの作成
let markerLabel = document.createElement("div");
markerLabel.classList.add("mark-label");
markerLabel.innerText = data.features[0].properties.points[0][0];
// ピン要素の作成
let iconImage = new PinElement({
glyph: markerLabel,
background: "#6f98efff",
borderColor: "#3718e6ff",
scale: 0.8,
});
// マーカー要素の作成
const marker = new AdvancedMarkerElement({
map,
position: schoolPosition,
title: data.features[0].properties.points[0][0],
content: iconImage.element,
});
最終的な JavaScript、CSS
index.js
async function initMap() {
const { Map } = await google.maps.importLibrary("maps");
const { AdvancedMarkerElement, PinElement } = await google.maps.importLibrary("marker");
const centerLocation = { lat: 35.681095, lng: 139.686144 };
const map = new Map(document.getElementById("map"), {
zoom: 14,
center: centerLocation,
mapId: "DEMO_MAP_ID", // デモ用マップID。本番環境では適切なマップIDに変更してください。
});
// 地図クリックイベント
map.addListener("click", (event) => {
const { latLng } = event;
const lat = latLng.lat();
const lng = latLng.lng();
// クリックした位置の小学校区ポリゴンを取得
fetch(`http://127.0.0.1:3000/get-gakku-polygon`, { // サーバーURLは適宜変更してください
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ lat, lng }),
})
.then((response) => response.json())
.then((data) => {
// GeoJSONデータを地図に追加
map.data.addGeoJson(data);
// 小学校の位置
const schoolPosition = {
lat: data.features[0].properties.point_coordinates[1],
lng: data.features[0].properties.point_coordinates[0],
};
// マーカーラベルの作成
let markerLabel = document.createElement("div");
markerLabel.classList.add("mark-label");
markerLabel.innerText = data.features[0].properties.points[0][0];
// ピン要素の作成
let iconImage = new PinElement({
glyph: markerLabel,
background: "#6f98efff",
borderColor: "#3718e6ff",
scale: 0.8,
});
// マーカー要素の作成
const marker = new AdvancedMarkerElement({
map,
position: schoolPosition,
title: data.features[0].properties.points[0][0],
content: iconImage.element,
});
})
.catch((error) => {
console.log(error);
});
});
// ポリゴンのスタイル設定
const polygonStyleOptions = {
strokeColor: "#810FCB",
strokeOpacity: 1.0,
strokeWeight: 2.0,
fillColor: "#810FCB",
fillOpacity: 0.5,
};
// 地図上のマルチポリゴンにスタイルを適用
map.data.setStyle((feature) => {
if (feature.getGeometry().getType() === "MultiPolygon") {
return polygonStyleOptions;
}
return null;
});
}
initMap();
.mark-label {
color: white;
font-size: 10px;
background-color: rgba(0, 0, 0, 0.5);
padding: 2px 10px;
border-radius: 8px;
flex: none;
transform: translateY(35px);
}
ポリゴン、マーカー、マーカーラベルの例

サーバーサイド(Node.js)
TerraMap APIを利用するには専用のAPIキーが必要になり、サーバープログラムでの使用を推奨しています。下記コードでは YOUR_TERRAMAP_API_KEY
部分にAPIキーを入力します。
/get-gakku-polygon
のエンドポイントは、Google Mapからの座標情報を受け取り小学校区ポリゴンを返すように作成しています。内部ではTerraMap APIのインターフェース仕様に従ったリクエストを実行しています。
const axios = require("axios");
const cors = require("cors");
const express = require("express");
const app = express();
// CORS設定 全てのオリジンを許可(開発用)
app.use(cors());
// JSONのパーサーを使用
app.use(express.json());
// TerraMap APIの小学校区ポリゴン取得エンドポイント
app.post("/get-gakku-polygon", async (req, res) => {
// リクエストボディから緯度経度を取得
const { lat, lng } = req.body;
if (!lat || !lng) {
return res.status(400).json({
error: "lat and lng are required",
});
}
try {
const response = await axios.post(
"https://tmapi.mapmarketing.jp/api/area",
{
layer_id: "10101", // 小学校区のレイヤーID:10101 中学校区のレイヤーID:10102
area_type: "coordinate", // 座標指定を選択
coordinates: [[lng, lat]],
output: "polygon,point", // ポリゴンとポイント情報(学校名)を取得
},
{
headers: {
"Content-Type": "application/json",
"X-API-KEY": "YOUR_TERRAMAP_API_KEY",
},
}
);
res.json(response.data);
} catch (error) {
console.error("get-gakku-polygons error:", error.message);
res.status(500).json({
error: "Failed to get gakku polygons",
});
}
});
// サーバー起動
app.listen(3000, () => {
console.log("TerraMap API中継サーバーがポート3000で起動中です");
});
ライブラリのインストール
npm install axios cors express
サーバー起動
node server.js
※ Node.js以外の言語でのTerraMap APIへのリクエスト例については、以下のスタートアップガイドをご参照下さい。