この記事は、「MIERUNE Advent Calendar 2020」の17日目の記事です。
LeafletでGeoPackageを読み込んで表示してみました
QGISでよく利用するGeoPackageですが、実はLeafletで読み込んで表示することもできたりします
LeafletでGeoPackageを読み込んで表示する場合は、GeoPackage JSを利用したleaflet-geopackageで実現できます。
利用データ
今回は、QGISのQuickOSMプラグインで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">© MIERUNE</a> <a href="https://www.maptiler.com/copyright/" target="_blank">© MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">© 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">© MIERUNE</a> <a href="https://www.maptiler.com/copyright/" target="_blank">© MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">© 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
表示されました
LeafletでGeoPackageを読み込んで表示ができました
LeafletでもGeoPackageを手軽に読み込むことができます
Webアプリケーションでも読めたりするので、GeoPackage好きなかたはゼヒお試しください!
今後、webpackで構築できるようにしたり、OpenLayersやMapbox GL JSのプラグインを構築できたらおもしろいなと思ったりしました
ちなみに、以前の記事、「色々なマップライブラリでポイント表示数の限界を探ってみた」のように、GeoPackageでも5万件の表示を検証してみましたが、GeoJSONと表示の重さは変わらなかったのでLeaflet側の限界なのかなと思いました...
Leafletについて、他にも記事を書いています。よろしければぜひ
tags - Leaflet
やってみたシリーズ
tags - Try