概要
地図アプリを開発していますが、たくさんの地図画像(PNG)が必要になりました。
「Python 用ライブラリの staticmap を使って OpenStreetMap の画像を取得する」方法を使っていましたが、Leaflet地図のデザインが今一つ(すみません。個人の主観です)なので、別の地図画像を探していました。
Geoloniaさんの地図は、月20,000回まで無料で地図を表示できますし、開発環境なら制限を気にせず無料で使えるので、ありがたいです。デザインも素晴らしく、こちらを使わせていただくことにしました。
最初はCanvasをtoDataUrlメソッドで取得できると考えていましたが、透明な画像しかキャプチャできず困っていました。Geoloniaの中の人に相談したら、「@geolonia/mbgl-export-control」というパッケージを紹介してもらいました。Geolonia Mapsの画像をダウンロードする方法を解説します。Node.jsを使って実装していきます。
環境
MacBook Air (M1)
node v14.2.0
npm 9.4.0
express、ejs、express-ejs-layoutsパッケージをインストール済み
publicフォルダーに「img」「css」「js」「json」ファイルを配置して、配信するようにしている
@geolonia/mbgl-export-control
@geolonia/mbgl-export-controlのGitHubを見てみましょう。
地図画像(Mapbox GL JS)をPNG画像でダウンロードするボタンを設置してくれるプラグインです。このプラグインを使うと、Geolonia Mapsの地図画像をダウンロードできるようになります。著作権表示も指定できる優れものです。
パッケージのインストール
初めに、パッケージをインストールします。@geolonia/mbgl-export-controlをバンドルするために、webpackもインストールしておきます。
$ npm install @geolonia/mbgl-export-control
$ npm install --save-dev webpack webpack-cli
地図表示用のejsファイル
次に、地図表示用のejsファイルを作成します。
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<title>Example: @geolonia/mbgl-export-control</title>
<style>
#map
{
width: 1000px;
height: 800px;
}
</style>
</head>
<body>
<p>/export-map?lat=緯度&lng=経度&zoom=倍率</p>
<div id="map"
data-lat="<%= lat || "34.704395" %>"
data-lng="<%= lng || "135.494771" %>"
data-zoom="<%= zoom || "14" %>"
></div>
<script type="text/javascript" src="https://cdn.geolonia.com/v1/embed?geolonia-api-key=YOUR-API-KEY"></script>
<script src=/js/bundle.js"></script>
</body>
</html>
GitHub の doc/index.html にあるサンプルを一部改変しました。
URLクエリパラメータ「?lat=緯度&lng=経度&zoom=倍率」で地図の緯度経度、拡大倍率を指定できるようにしました。地図の表示とダウンロードボタンを設置するコードは、src/js/app.jsに記載します。
Geolonia Mapsは、次のscriptタグを入れるだけで使えるようになります。開発環境では、共通のAPI KEY「YOUR-API-KEY」を指定するだけで、簡単に地図を表示できます。至れり尽くせりで開発者に優しいですね。
<script type="text/javascript" src="https://cdn.geolonia.com/v1/embed?geolonia-api-key=YOUR-API-KEY"></script>
地図の表示とダウンロードボタンの設置
地図の表示とコントロール部分のコードをJavaScriptで記載します。
import ExportControl from '@geolonia/mbgl-export-control'
const map = new mapboxgl.Map("#map");
// Add the control to download png.
map.addControl(new ExportControl({
dpi: 300,
attribution: "© Geolonia | © OpenStreetMap Contributors",
}));
READMEのサンプルを一部改変しました。
オプションで著作権表示(attribution)を指定できます。"© Geolonia | © OpenStreetMap Contributors"と、著作権表示して使うことができます。
webpackでバンドルする
webpackを使うと、Node.jsのモジュールシステムをブラウザでも利用できるようになります。webpack.config.jsは最小の構成としました。
const path = require('path');
module.exports = {
mode: 'development',
entry: './src/js/app.js',
output: {
path: path.resolve(__dirname, 'public'),
filename: "js/bundle.js"
}
}
コンソールで、Webpackを実行すると、public/js/bundle.jsに地図表示・ダウンロードのJavacriptコードがバンドルされて出力されます。
$ webpack
バンドルしたJSファイル(public/js/bundle.js)を index.ejsで読み込みます。
<script src=/js/bundle.js"></script>
Expressでレンダーする
こちらの環境では、mapsController.js で地図関連のejsをレンダリングしています。
module.exports = {
export_map: (req, res) => {
res.render("index", {
lat: req.query.lat,
lng: req.query.lng,
zoom: req.query.zoom,
});
},
...
Expressを使って、index.ejsファイルを表示できるようにします。URLクエリパラメータ(lat、lng、zoom)をejsに送ることで、任意の地図地点を指定できます。
地図の表示とダウンロード
ローカルでサーバーを立ち上げて、ブラウザで表示します。
http://localhost:3000/export-map?lat=35.6809591&lng=139.7673068&zoom=14
ダウンロードボタンが設置できたので、クリックして画像をダウンロードしてください。オプションで指定した著作権表示が画像右下に入りますので、このまま使うことができます。これで完成です!
初心者なので、もっと良いやり方、書き方があればぜひ教えてください。記事を更新してより良いものにしたいと考えています。よろしくお願いいたします。