Leaflet と OpenStreetMap で伊能忠敬の古地図を表示してみよう


OpenStreetMap Advent Calendar 2017 へ投稿の記事です

Leaflet.js

ブラウザで地図を表示するためのオープンソースクライアントライブラリです。
Google Maps に近いものですが、表示する地図を OSM や国土地理院の地図などユーザの任意の地図にできます。

今回はこの Leaflet.js に OSM の地図を表示して、なおかつ古地図画像をプロットしてみたいと思います。
地図にプロットする古地図は国土地理院の「古地図コレクション」を引用します。

引用する古地図画像は、正確無比と名高いかの伊能忠敬の越中 能登 能登島の図にしました。

まずは地図を作成するHTMLとCSSを用意します。

<div id="map"></div>
html, body {
  height: 100%;
}
#map {
  position: relative;
  width: 100%;
  height: auto;
  min-height: 100%;
  background-color: #ddd;
}

.leaflet-tile-pane > .leaflet-layer {
    opacity: 0 !important;
}

次に Leaflet.js を使って地図を作成します。

var map = L.map('map', {
  attribution : '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
  center: [37.33522435930641, 136.74133300781253],
  zoom: 9
});

Leaflet.js では、ここに独自に画像を表示し WEB 地図のように拡大やドラッグ移動などできるようにすることもできるのですが、今回は OSM のタイルサーバから世界地図を読み込むようにしました。

const layerUrl = 'http://{s}.tile.osm.org/{z}/{x}/{y}.png';
var tileLayer = L.tileLayer(layerUrl).addTo(map);

画像をプロットする

地図に画像をプロットします。
プロットする時は、座標系での数値していになります。
Leaflet.js には画面のピクセルと座標系を相互変換できる関数も用意されていますが、今回は適当に配置 笑

let ne = { lat: 36.5, lng: 136 };
let imageUrl = "http://kochizu.gsi.go.jp/map-thumbnails/inouzu-saisyokuzu/i084.jpg",
imageBounds = new L.LatLngBounds(
  [ne.lat, ne.lng],
  [ne.lat + 0.75, ne.lng + 1.5]
 );
L.imageOverlay(imageUrl, imageBounds).addTo(map);

結果

このように地図がクライアントに表示されました。
OSM のタイル画像が読み込まれるコンテナを CSS で opacity: 0 !important; として背景を透過しています。

OSM の座標を利用して実際の座標に合わせてプロットしたかったのですが時間がなくて断念しました。笑
実際は以下の画像のようにプロットされています。