Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

はじめに

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>

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

mix_dvd
ExcelのマクロやWebアプリケーション、iOSアプリを作っています。 また、しまねソフト研究開発センター専門研究員の業務を受託しています。http://www.s-itoc.jp
http://blueomega.jp
s-itoc
しまねソフト研究開発センター(ITOC)はITを活用する企業の支援と研究開発の拠点です。
http://www.s-itoc.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした