11
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

MIERUNEAdvent Calendar 2020

Day 17

LeafletでGeoPackageを読み込んで表示してみた

Posted at



この記事は、「MIERUNE Advent Calendar 2020」の17日目の記事です。

LeafletでGeoPackageを読み込んで表示してみました :tada:

QGISでよく利用するGeoPackageですが、実はLeafletで読み込んで表示することもできたりします :bulb:

LeafletでGeoPackageを読み込んで表示する場合は、GeoPackage JSを利用したleaflet-geopackageで実現できます。


利用データ

今回は、QGISQuickOSMプラグインでOpenStreetMapのshopデータを5000件程度準備してGeoPackageで保存しました。


Leaflet

次に、Leafletで構築していきます。
leaflet-geopackageは、webpackに対応していないみたいなので今回はプレーンな構成で構築してみます。


全体構成

画像

index.html

<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Leaflet Sample</title>
        <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
        <link href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" rel="stylesheet" />

        <script src="https://unpkg.com/@ngageoint/leaflet-geopackage@3.0.3/dist/leaflet-geopackage.min.js"></script>

        <link href="css/style.css" rel="stylesheet" />
    </head>
    <body>
        <div id="map"></div>
        <script src="js/app.js"></script>
    </body>
</html>

LeafletをCDNで読み込みます。

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

leaflet-geopackageをCDNで読み込みます。

<script src="https://unpkg.com/@ngageoint/leaflet-geopackage@3.0.3/dist/leaflet-geopackage.min.js"></script>

/css

style.css

html, body {
    height: 100%;
    padding: 0;
    margin: 0;
}

#map {
    z-index: 0;
    height: 100%;
}

/js

app.js

// MIERUNE Streets読み込み
const m_streets = new L.tileLayer(
    'https://api.maptiler.com/maps/jp-mierune-streets/256/{z}/{x}/{y}.png?key=[APIキー]',
    {
        attribution:
            '<a href="https://maptiler.jp/" target="_blank">&copy; MIERUNE</a> <a href="https://www.maptiler.com/copyright/" target="_blank">&copy; MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>',
    }
);

// MIERUNE Gray読み込み
const m_gray = new L.tileLayer(
    'https://api.maptiler.com/maps/jp-mierune-gray/256/{z}/{x}/{y}.png?key=[APIキー]',
    {
        attribution:
            '<a href="https://maptiler.jp/" target="_blank">&copy; MIERUNE</a> <a href="https://www.maptiler.com/copyright/" target="_blank">&copy; MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>',
    }
);

// MAP読み込み
const map = L.map('map', {
    center: [43.3179, 142.6308],
    zoom: 8,
    zoomControl: true,
    layers: [m_streets],
});

//背景レイヤ
const Map_BaseLayer = {
    'MIERUNE Streets': m_streets,
    'MIERUNE Gray': m_gray,
};

//レイヤ設定
L.control.layers(Map_BaseLayer, null).addTo(map);

//スケール設定
L.control
    .scale({
        imperial: false,
        maxWidth: 300,
    })
    .addTo(map);

// GeoPackage読み込み
L.geoPackageFeatureLayer([], {
    // GeoPackageファイル指定
    geoPackageUrl: './data/shop.gpkg',
    // レイヤ名指定
    layerName: 'shop',
    pointToLayer: function (feature, layer) {
        return L.circleMarker(layer, {
            color: '#014c86',
            radius: 3,
            weight: 1,
            opacity: 0.7,
            fill: true,
            fillColor: '#014c86',
            fillOpacity: 0.7
        });
    },
    onEachFeature: function (feature, layer) {
        const field =
            `fid: ${feature.properties.fid} <br>
            full_id: ${feature.properties.full_id} <br>
            osm_id: ${feature.properties.osm_id} <br>
            name: ${feature.properties.name} <br>
            shop: ${feature.properties.shop}`;
        layer.bindPopup(field);
    }
}).addTo(map);

GeoPackageを読み込んで表示します。

// GeoPackage読み込み
L.geoPackageFeatureLayer([], {
    // GeoPackageファイル指定
    geoPackageUrl: './data/shop.gpkg',
    // レイヤ名指定
    layerName: 'shop',
    pointToLayer: function (feature, layer) {
        return L.circleMarker(layer, {
            color: '#014c86',
            radius: 3,
            weight: 1,
            opacity: 0.7,
            fill: true,
            fillColor: '#014c86',
            fillOpacity: 0.7
        });
    },
    onEachFeature: function (feature, layer) {
        const field =
            `fid: ${feature.properties.fid} <br>
            full_id: ${feature.properties.full_id} <br>
            osm_id: ${feature.properties.osm_id} <br>
            name: ${feature.properties.name} <br>
            shop: ${feature.properties.shop}`;
        layer.bindPopup(field);
    }
}).addTo(map);


簡易ローカルサーバーで確認してみます。

python -m http.server 8000

表示されました :grinning:

画像


LeafletでGeoPackageを読み込んで表示ができました :thumbsup:

LeafletでもGeoPackageを手軽に読み込むことができます :bulb:
Webアプリケーションでも読めたりするので、GeoPackage好きなかたはゼヒお試しください!

今後、webpackで構築できるようにしたり、OpenLayersやMapbox GL JSのプラグインを構築できたらおもしろいなと思ったりしました :grinning:

ちなみに、以前の記事、「色々なマップライブラリでポイント表示数の限界を探ってみた」のように、GeoPackageでも5万件の表示を検証してみましたが、GeoJSONと表示の重さは変わらなかったのでLeaflet側の限界なのかなと思いました...


Leafletについて、他にも記事を書いています。よろしければぜひ :bow:
tags - Leaflet

やってみたシリーズ :grinning:
tags - Try



book

11
2
0

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
11
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?