LoginSignup
22

More than 5 years have passed since last update.

Leafletと国土地理院のGSIタイルデータを使った地図アプリの作成

Last updated at Posted at 2016-11-17

はじめに

Webアプリケーションで地図データを扱うAPIの代表格はGoogleMapsAPIかと思いますが、いろいろな制約があったりするので、別の方法で地図を使う方法がないかと検索したらLeafletというJavaScriptライブラリと国土地理院のデータが使用できるようなので、試した結果をまとめます。

Leaflet

非常に軽量なライブラリで、サクサク動く上に必要最低限の機能がそろっています。
http://leafletjs.com

国土地理院

GoogleMapsAPIと同じような使い方ができるデータが公開されています。
普通の地図から複数年の航空写真、災害時の写真など興味深いものがいっぱいあるので、これを使わないのはもったい無い。
http://maps.gsi.go.jp/development/ichiran.html

クイックスタートを読んでみる

LeafletのWebサイトにクイックスタートがあるので見てみます。
http://leafletjs.com/examples/quick-start/

...英語でした(汗)

でも、ソースコードをまとめてみれば何かわかるかもしれないので、ソースコードっぽい部分をまとめてみます。

 <link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.1/dist/leaflet.css" />
 <script src="https://unpkg.com/leaflet@1.0.1/dist/leaflet.js"></script>
 <div id="mapid"></div>
#mapid { height: 180px; }
var mymap = L.map('mapid').setView([51.505, -0.09], 13);
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
    attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://mapbox.com">Mapbox</a>',
    maxZoom: 18,
    id: 'your.mapbox.project.id',
    accessToken: 'your.mapbox.public.access.token'
}).addTo(mmap);
var marker = L.marker([51.5, -0.09]).addTo(mmap);
var circle = L.circle([51.508, -0.11], {
    color: 'red',
    fillColor: '#f03',
    fillOpacity: 0.5,
    radius: 500
}).addTo(mmap);
var polygon = L.polygon([
    [51.509, -0.08],
    [51.503, -0.06],
    [51.51, -0.047]
]).addTo(mmap);
marker.bindPopup("<b>Hello world!</b><br>I am a popup.").openPopup();
circle.bindPopup("I am a circle.");
polygon.bindPopup("I am a polygon.");
var popup = L.popup()
    .setLatLng([51.5, -0.09])
    .setContent("I am a standalone popup.")
    .openOn(mmap);
function onMapClick(e) {
    alert("You clicked the map at " + e.latlng);
}
mymap.on('click', onMapClick);
var popup = L.popup();
function onMapClick(e) {
    popup
        .setLatLng(e.latlng)
        .setContent("You clicked the map at " + e.latlng.toString())
        .openOn(mymap);
}
mymap.on('click', onMapClick);

...うん、わからない。

地図画像の下に「See this example stand-alone.」とリンクが貼ってあるので、クリックしてみる。
http://leafletjs.com/examples/quick-start/example.html

表示されたページのソースコードを表示すると以下のようになっていた。

example.html
<!DOCTYPE html>
<html>
<head>

    <title>Quick Start - Leaflet</title>

    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <link rel="shortcut icon" type="image/x-icon" href="docs/images/favicon.ico" />

    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.1/dist/leaflet.css" />
    <script src="https://unpkg.com/leaflet@1.0.1/dist/leaflet.js"></script>

</head>
<body>

<div id="mapid" style="width: 600px; height: 400px;"></div>
<script>

    var mymap = L.map('mapid').setView([51.505, -0.09], 13);

    L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpandmbXliNDBjZWd2M2x6bDk3c2ZtOTkifQ._QA7i5Mpkd_m30IGElHziw', {
        maxZoom: 18,
        attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
            '<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
            'Imagery © <a href="http://mapbox.com">Mapbox</a>',
        id: 'mapbox.streets'
    }).addTo(mymap);

    L.marker([51.5, -0.09]).addTo(mymap)
        .bindPopup("<b>Hello world!</b><br />I am a popup.").openPopup();

    L.circle([51.508, -0.11], 500, {
        color: 'red',
        fillColor: '#f03',
        fillOpacity: 0.5
    }).addTo(mymap).bindPopup("I am a circle.");

    L.polygon([
        [51.509, -0.08],
        [51.503, -0.06],
        [51.51, -0.047]
    ]).addTo(mymap).bindPopup("I am a polygon.");


    var popup = L.popup();

    function onMapClick(e) {
        popup
            .setLatLng(e.latlng)
            .setContent("You clicked the map at " + e.latlng.toString())
            .openOn(mymap);
    }

    mymap.on('click', onMapClick);

</script>

</body>
</html>

とりあえず、このソースをコピーしてデスクトップにHTMLファイルとして保存すると...

スクリーンショット 2016-11-16 19.53.18.png

できた!

...でも、これでは当初のテーマである国土地理院のデータを使っていないため、まだまだこれから。

地図データを変えてみる

25行目付近のコードがちょっと気になる。

    L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpandmbXliNDBjZWd2M2x6bDk3c2ZtOTkifQ._QA7i5Mpkd_m30IGElHziw', {
        maxZoom: 18,
        attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
            '<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
            'Imagery © <a href="http://mapbox.com">Mapbox</a>',
        id: 'mapbox.streets'
    }).addTo(mymap);

「https://〜」で始まる部分と同じような表記が国土地理院のGSIページにあるので、勝手に書き換えてみる(^-^)
maxZoomは地理院タイルの情報にズームレベルが書いてあるので、ちょっと関係あるかもしれない。

    L.tileLayer('http://cyberjapandata.gsi.go.jp/xyz/ort/{z}/{x}/{y}.jpg', {
        maxZoom: 18
    }).addTo(mymap);

書き換えたら再読込。

スクリーンショット 2016-11-17 8.56.45.png

...何も表示されない。

ズームレベルをどんどん下げてみると、何か表示された。

スクリーンショット 2016-11-17 8.58.14.png

地図を移動させると日本が出てきた。

スクリーンショット 2016-11-17 8.59.43.png

きっと、中心座標が間違っているからに違いない。

中心座標を変えてみる

    var mymap = L.map('mapid').setView([51.505, -0.09], 13);

となっている部分を去年国宝になった松江城の座標(35.47507, 133.05075)に書き換えてみる。

    var mymap = L.map('mapid').setView([35.47507, 133.05075], 13);

スクリーンショット 2016-11-17 9.07.02.png

...あれ、まだダメだ(汗)

地図の描画以降に書いてるものが邪魔しているかもしれない。

「L.marker〜mmap.on(〜)」までを「/* 〜 */」で囲って無効にしてもう一度再読込。

スクリーンショット 2016-11-17 9.09.52.png

来た!

全ソースコード

できたとこまでに必要なソースコードだけにまとめるととてもシンプル(^-^)

example.html
<!DOCTYPE html>
<html>
<head>

    <title>Quick Start - Leaflet</title>

    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <link rel="shortcut icon" type="image/x-icon" href="docs/images/favicon.ico" />

    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.1/dist/leaflet.css" />
    <script src="https://unpkg.com/leaflet@1.0.1/dist/leaflet.js"></script>

</head>
<body>

<div id="mapid" style="width: 600px; height: 400px;"></div>
<script>

    var mymap = L.map('mapid').setView([35.47507, 133.05075], 13);

    L.tileLayer('http://cyberjapandata.gsi.go.jp/xyz/ort/{z}/{x}/{y}.jpg', {
        maxZoom: 18
    }).addTo(mymap);

</script>

</body>
</html>

よし、これから何しよう!!

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
22