TOP > デジタル地図の開発者ブログ > LeafletでMapFan APIの地図をレイヤー表示する
2020.02.28

LeafletでMapFan APIの地図をレイヤー表示する

前回の記事 では、LeafletでMapFan APIの地図を表示するシンプルな手法についてご紹介しました。
今回は、Leafletのレイヤー機能 を用いて、デザインの異なる地図への表示の切り替えや、お客様が保有するデータを地図上に表示する手法についてご紹介します。

MapFan API 仕様書ダウンロードはこちら>

レイヤーの種類

Leafletでは、ベースレイヤー オーバーレイレイヤー を利用できます。

ベースレイヤー は、地図ビューの最下層に表示するレイヤーです。
複数のベースレイヤーを登録することで、デザインの異なる地図へ表示を切り替えることが可能になりますが、同時に表示できるレイヤーは一つのみです。

オーバーレイレイヤー は、ベースレイヤーの上に重ねて表示するレイヤーで、複数を同時に表示することも可能です。
地図上で強調表示したい地点やエリアを、ポイント・ポリライン・ポリゴン・GeoJsonなどの図形を用いて表現する場合、表示物の内容や種別に応じて登録するオーバーレイレイヤーを切り分けることで、グループ単位で一括表示ON/OFFが可能になるなど、表示物の管理が容易になります。

また、作成した表示物のレイヤーを Control.Layers に登録することで、表示を制御できるUIコントローラーをLeafletが用意してくれます。
ベースレイヤーはラジオボタンによる切り替え、オーバーレイレイヤーはチェックボックスによる表示ON/OFFの機能が提供されます。
デフォルトの見た目は下図の通りですが、cssによるデザイン変更は可能です。

ベースレイヤー(WMTSタイル)

それでは、ベースレイヤーの実装についてご説明します。
実装は、前回の記事の 認証APIのコールバック の中で行います。

ベースレイヤー実装の流れとしては、以下のようになります。

●1. Layerの生成
●2. (1)のうち初期表示するLayerをMapへ設定
●3. UIコントローラー上の表示名と(1)のLayerを紐付け
●4. (3)をL.control.layersへ設定、L.control.layersをMapへ設定

ここでは、『地図画像取得API:map』の mapstyleパラメータ を使って、異なる地図デザインのレイヤーを用意して地図の見た目を変化させてみます。

// ベースレイヤーの表示オプション
var baseOptions = {
    minZoom: 6,
    maxZoom: 21,
    attribution: '<span class="copyright">&copy GeoTechnologies, Inc.</span> <a href="https://api-auth.mapfan.com/terms/mfapi_terms.pdf">利用規約</a>',
};

var mapUrl = 'https://api-map.mapfan.com/v1/map?' + 'key=' + result.key + '&tilematrix=EPSG:3857:{z}&tilecol={x}&tilerow={y}';

// ●1. Layerの生成
// mapstyle=std_pc(標準デザイン(デフォルト))
var standard = L.tileLayer(mapUrl, baseOptions);
// mapstyle=gray_pc(グレースケール地図)
var gray = L.tileLayer(mapUrl + '&mapstyle=gray_pc', baseOptions);
// mapstyle=rpg_pc(RPG風地図)
var rpg = L.tileLayer(mapUrl + '&mapstyle=rpg_pc', baseOptions);
// mapstyle=antique_pc(古地図風地図)
var antique = L.tileLayer(mapUrl + '&mapstyle=antique_pc', baseOptions);
// mapstyle=tourism_pc(おもてなしマップ(カラーユニバーサルデザイン対応))
var tourism = L.tileLayer(mapUrl + '&mapstyle=tourism_pc', baseOptions);

// LeafletのMapクラスに、地図を表示する領域のdivタグのidを指定
// 初期表示位置・スケールは、東京駅 スケール17に設定
var map = L.map('map', {
    center: L.latLng(35.68116552628331, 139.76719388020982),
    zoom: 17,
    // ●2. (1)のうち初期表示するLayerをMapへ設定
    layers: [standard],
});

// ●3. UIコントローラー上の表示名と(1)のLayerを紐付け
var baseLayerControls = {
    '標準': standard,
    'グレー': gray,
    'RPG風': rpg,
    '古地図風': antique,
    'おもてなし': tourism,
};

// ●4. (3)をL.control.layersへ設定、L.control.layersをMapへ設定
L.control.layers(baseLayerControls, null, {
    collapsed: false,
}).addTo(map);

ここまでの実装で、以下のような画面になります。

他にもMapFan APIでは、注記(駅名や施設名等の表記)を13カ国(14言語)の表記でご利用いただける多言語地図もご用意しております。(別途オプション契約が必要です。)
多言語地図は『地図画像取得API:map』の langパラメータ で言語を指定して利用します。
また、全ての言語は日本語との併記が可能です。

// ●1. Layerの生成
// 標準デザイン x 日本語
var ja = L.tileLayer(mapUrl + '&lang=ja', baseOptions);
// 標準デザイン x 英語
var en = L.tileLayer(mapUrl + '&lang=en', baseOptions);
// 標準デザイン x 中国語(簡体字)
var zh2 = L.tileLayer(mapUrl + '&lang=zh2', baseOptions);
// 標準デザイン x 中国語(繁体字)
var zh1 = L.tileLayer(mapUrl + '&lang=zh1', baseOptions);
// 標準デザイン x 韓国語
var ko = L.tileLayer(mapUrl + '&lang=ko', baseOptions);
// 標準デザイン x タイ語
var th = L.tileLayer(mapUrl + '&lang=th', baseOptions);
// 標準デザイン x インドネシア語
var id = L.tileLayer(mapUrl + '&lang=id', baseOptions);
// 標準デザイン x フランス語
var fr = L.tileLayer(mapUrl + '&lang=fr', baseOptions);
// 標準デザイン x ドイツ語
var de = L.tileLayer(mapUrl + '&lang=de', baseOptions);
// 標準デザイン x ベトナム語
var vi = L.tileLayer(mapUrl + '&lang=vi', baseOptions);
// 標準デザイン x スペイン語
var es = L.tileLayer(mapUrl + '&lang=es', baseOptions);
// 標準デザイン x イタリア語
var it = L.tileLayer(mapUrl + '&lang=it', baseOptions);
// 標準デザイン x ロシア語
var ru = L.tileLayer(mapUrl + '&lang=ru', baseOptions);
// 標準デザイン x ポルトガル語
var pt = L.tileLayer(mapUrl + '&lang=pt', baseOptions);
// 標準デザイン x 併記(日本語 - 英語)
var ja_en = L.tileLayer(mapUrl + '&lang=ja,en', baseOptions);

// LeafletのMapクラスに、地図を表示する領域のdivタグのidを指定
// 初期表示位置・スケールは、東京駅 スケール17に設定
var map = L.map('map', {
    center: L.latLng(35.68116552628331, 139.76719388020982),
    zoom: 17,
    // ●2. 初期表示するLayerをMapへ設定
    layers: [ja]
});

// ●3. UIコントローラー上の表示名と(1)のLayerを紐付け
var baseLayerControls = {
    '日本語': ja,
    '英語': en,
    '中国語(簡体字)': zh2,
    '中国語(繁体字)': zh1,
    '韓国語': ko,
    'タイ語': th,
    'インドネシア語': id,
    'フランス語': fr,
    'ドイツ語': de,
    'ベトナム語': vi,
    'スペイン語': es,
    'イタリア語': it,
    'ロシア語': ru,
    'ポルトガル語': pt,
    '併記(日本語・英語)': ja_en,
};

// ●4. (3)をL.control.layersへ設定、L.control.layersをMapへ設定
L.control.layers(baseLayerControls, null, {
    collapsed: false,
}).addTo(map);

成果物は、以下のようになります。

オーバーレイレイヤー(WMTSタイル)

次に、オーバーレイレイヤーについてです。
手順は、ベースレイヤーとほぼ同様です。

MapFan APIは『地図画像取得API:map』の targetパラメータ を用いると、地図を背景部と注記部でレイヤー分割 することが可能です。

前述の「RPG風地図」や「古地図風地図」では、各デザイン専用の外国語フォントの用意が無いため、背景部・注記部一体での多言語地図はご提供しておりませんが、注記部を標準地図デザインから取得してオーバーレイレイヤーとして重ねることで、「多言語化した特殊なデザインの地図」を表示できます。

// ●1. Layerの生成
// [ベースレイヤー] mapstyle=antique_pc(古地図風地図)(背景のみ)
var backAntique = L.tileLayer(mapUrl + '&target=1' + '&mapstyle=antique_pc', baseOptions);

// [オーバーレイレイヤー] 標準デザイン x 日本語(注記のみ)
var labelJa = L.tileLayer(mapUrl + '&target=2' + '&lang=ja', baseOptions);
// [オーバーレイレイヤー] 標準デザイン x 英語(注記のみ)
var labelEn = L.tileLayer(mapUrl + '&target=2' + '&lang=en', baseOptions);
// [オーバーレイレイヤー] 標準デザイン x 中国語(簡体字)(注記のみ)
var labelZh2 = L.tileLayer(mapUrl + '&target=2' + '&lang=zh2', baseOptions);
// [オーバーレイレイヤー] 標準デザイン x 中国語(繁体字)(注記のみ)
var labelZh1 = L.tileLayer(mapUrl + '&target=2' + '&lang=zh1', baseOptions);
// [オーバーレイレイヤー] 標準デザイン x 韓国語(注記のみ)
var labelKo = L.tileLayer(mapUrl + '&target=2' + '&lang=ko', baseOptions);
// [オーバーレイレイヤー] 標準デザイン x タイ語(注記のみ)
var labelTh = L.tileLayer(mapUrl + '&target=2' + '&lang=th', baseOptions);
// [オーバーレイレイヤー] 標準デザイン x インドネシア語(注記のみ)
var labelId = L.tileLayer(mapUrl + '&target=2' + '&lang=id', baseOptions);
// [オーバーレイレイヤー] 標準デザイン x フランス語(注記のみ)
var labelFr = L.tileLayer(mapUrl + '&target=2' + '&lang=fr', baseOptions);
// [オーバーレイレイヤー] 標準デザイン x ドイツ語(注記のみ)
var labelDe = L.tileLayer(mapUrl + '&target=2' + '&lang=de', baseOptions);
// [オーバーレイレイヤー] 標準デザイン x ベトナム語(注記のみ)
var labelVi = L.tileLayer(mapUrl + '&target=2' + '&lang=vi', baseOptions);
// [オーバーレイレイヤー] 標準デザイン x スペイン語(注記のみ)
var labelEs = L.tileLayer(mapUrl + '&target=2' + '&lang=es', baseOptions);
// [オーバーレイレイヤー] 標準デザイン x イタリア語(注記のみ)
var labelIt = L.tileLayer(mapUrl + '&target=2' + '&lang=it', baseOptions);
// [オーバーレイレイヤー] 標準デザイン x ロシア語(注記のみ)
var labelRu = L.tileLayer(mapUrl + '&target=2' + '&lang=ru', baseOptions);
// [オーバーレイレイヤー] 標準デザイン x ポルトガル語(注記のみ)
var labelPt = L.tileLayer(mapUrl + '&target=2' + '&lang=pt', baseOptions);

// LeafletのMapクラスに、地図を表示する領域のdivタグのidを指定
// 初期表示位置・スケールは、東京駅 スケール17に設定
var map = L.map('map', {
    center: L.latLng(35.68116552628331, 139.76719388020982),
    zoom: 17,
    // ●2. 初期表示するLayerをMapへ設定
    layers: [backAntique, labelJa],
});

// ●3. [ベースレイヤー] UIコントローラー上の表示名と(1)のLayerを紐付け
var baseLayerControls = {
    '古地図風(背景のみ)': backAntique,
};

// ●3. [オーバーレイレイヤー] UIコントローラー上の表示名と(1)のLayerを紐付け
var overlayLayerControls = {
    '日本語(注記のみ)': labelJa,
    '英語(注記のみ)': labelEn,
    '中国語(簡体字)(注記のみ)': labelZh2,
    '中国語(繁体字)(注記のみ)': labelZh1,
    '韓国語(注記のみ)': labelKo,
    'タイ語(注記のみ)': labelTh,
    'インドネシア語(注記のみ)': labelId,
    'フランス語(注記のみ)': labelFr,
    'ドイツ語(注記のみ)': labelDe,
    'ベトナム語(注記のみ)': labelVi,
    'スペイン語(注記のみ)': labelEs,
    'イタリア語(注記のみ)': labelIt,
    'ロシア語(注記のみ)': labelRu,
    'ポルトガル語(注記のみ)': labelPt,
};

// ●4. (3)をL.control.layersへ設定、L.control.layersをMapへ設定
L.control.layers(baseLayerControls, overlayLayerControls, {
    collapsed: false,
}).addTo(map);

成果物は、以下のようになります。

オーバーレイレイヤー(図形)

オーバーレイレイヤーには、ここまででご紹介してきたWMTS配信の地図タイル以外のLayerも設定可能です。
Leafletに用意されている「地点をアイコン表示できるMarker」「領域を示すPolyline・Polygon」や、外部ファイルで用意して取り込むことのできる「GeoJson」なども、Layerクラスを継承しているため利用できます。

以降でご紹介する表示物の緯度経度情報は、弊社の地図データベース商品である MapFan DB を加工して抽出しています。
MapFan APIから取得可能なデータ・情報ではございませんのでご注意ください。

// [ベースレイヤー] MapFan API 標準デザイン
var standard = L.tileLayer(mapUrl, baseOptions);

// ●1. Layerの生成
// [オーバーレイレイヤー] 山手線 駅
var shibuya = L.marker(/* 渋谷駅の緯度経度 */);
var harajuku = L.marker(/* 原宿駅の緯度経度 */);
var yoyogi = L.marker(/* 代々木駅の緯度経度 */);
var shinjuku = L.marker(/* 新宿駅の緯度経度 */);
// [オーバーレイレイヤー] 山手線 駅一覧
var yamanoteStations = L.layerGroup(/* 作成した山手線 駅の配列([shibuya, harajuku, yoyogi, shinjuku...])*/)

// [オーバーレイレイヤー] 山手線 線路
var yamanoteLine = L.polyline(/* 山手線 線路形状の緯度経度点列 */)

// LeafletのMapクラスに、地図を表示する領域のdivタグのidを指定
// 初期表示位置・スケールは、東京駅 スケール17に設定
var map = L.map('map', {
    center: L.latLng(35.68116552628331, 139.76719388020982),
    zoom: 17,
    // ●2. (1)のうち初期表示するLayerをMapへ設定
    // オーバーレイレイヤーは、いずれも初期表示なし
    layers: [standard],
});

// ●3. [オーバーレイレイヤー] UIコントローラー上の表示名と(1)のLayerを紐付け
var overlayLayerControls = {
    '山手線(駅)': yamanoteStations,
    '山手線(線路)': yamanoteLine,
};

// ●4. (3)をL.control.layersへ設定、L.control.layersをMapへ設定
// ベースレイヤーは固定・UI表示不要なため、nullを設定
L.control.layers(null, overlayLayerControls, {
    collapsed: false,
}).addTo(map);

// 地図表示範囲を、山手線 線路領域にフィット
map.fitBounds(yamanoteLine.getBounds());

成果物は、以下のようになります。

外部ファイルで用意したGeoJsonデータを読み込んで表示させる例は下記の通りです。
ここでは、GeoJsonの読み込みはjQueryの$.getJSONメソッドで行っています。

// GeoJsonファイルの読み込み
$.getJSON('GeoJsonファイルのパス', function(data) {
    // ●1. Layerの生成
    var geoJson = L.geoJson(data);

    // LeafletのMapクラスに、地図を表示する領域のdivタグのidを指定
    // 初期表示位置・スケールは、東京駅 スケール17に設定
    var map = L.map('map', {
        center: L.latLng(35.68116552628331, 139.76719388020982),
        zoom: 6,
        // ●2. (1)のうち初期表示するLayerをMapへ設定
        layers: [standard],
    });

    // ●3. UIコントローラー上の表示名と(1)のLayerを紐付け
    var overlayLayerControls = {
        'GeoJson': geoJson,
    };

    // ●4. (3)をL.control.layersへ設定、L.control.layersをMapへ設定
    L.control.layers(null, overlayLayerControls, {
        collapsed: false,
    }).addTo(map);

    // L.control.layers上でオーバーレイレイヤーの表示操作が行われた際、地図表示範囲をオーバーレイレイヤー領域にフィット
    map.on('overlayadd', (layer) => {
        map.fitBounds(layer.layer.getBounds())
    })
});

成果物は、以下のようになります。
※上記のソースコードをベースに、複数のGeoJsonファイルの読み込みや、図形のデザイン変更・Popup表示設定なども行っています。

まとめ

今回は、MapFan APIおよび弊社データベース商品のMapFan DBを用いて、様々な地図表示の手法についてご紹介しました。
お客様の方で保有する位置情報をLeafletで表示する際にお役立ていただければ幸いです。

次回は、MapFan APIの検索や経路といった、地図表示以外の機能についてご紹介したいと思います。

ジオテクノロジーズの地図API MapFan APIのお問い合わせは こちら>

MapFan API 仕様書ダウンロードは こちら>

MapFan APIの詳細は こちら>




法人向けサービスに関するお問い合わせはこちらから

法人向けサービスに関するお問い合わせはこちらから

関連サービス

関連記事