Leafletは言わずと知れた地図作成・表示のためのJavascriptライブラリです.
BlazorはC#側からJavascriptを呼び出すことが出来るようになっていますので,Blazorアプリ上でLeafletを使って地図作成・表示が可能です.
C#からの呼び出しを簡単に行うために,C#とJavascriptの橋渡しをするラッパーがいくつか公開されていますので,今回はそのうちの一つを使った方法をまとめておきます.
今回使うのはBlazor Leafletというwrapperで,チュートリアルもそこそこ書かれていますし,サンプルプログラムも公開されているので,基本的にその通り作っていけば動くと思いますが....まとめておきます.
以下では,Blazor Serverサイドで実行例を示していますが,webassemblyでも同じように動きます.
Blazor Serverアプリのプロジェクトを作る
Blazor Server のプロジェクトを作ります.
テンプレートからアプリが作成されるので,実行するとHello Worldが起ち上がるはずです.
BlazorLeafletを読み込む
ライブラリ(BlazorLeaflet)をGitHubからダウンロードして,プロジェクトに組み込みます.
Zipでダウンロードして,解凍します.BlazorLeafletというフォルダの中にBlazorLeaflet.slnがあるので,VisualStudioで開くと,サンプルプロジェクト等も確認できます.
やり方は色々あると思いますが,先ほど作ったBlazor ServerのプロジェクトにBlazorLeafletを追加します.「ファイル」−「追加」−「既存のプロジェクト」,または「ソリューションの上で右クリック」-「追加」-「既存のプロジェクト」と進んで,BlazorLeaflet/BlazorLeaflet.csprojを選択して追加します.Visual StudioのスクショはWindows版のものですが,Macでも大体同じような感じです.
追加できたら,Blazor Serverアプリ側の依存関係を設定します.
「依存関係」の上で右クリックし,「プロジェクト参照の追加」からBlazorLeafletを追加します.
Leafletを入れておく
肝心のLeafletをBlazorServerアプリのwwwrootフォルダに入れておきます.
今回は,以下からLeaflet 1.8.0をダウンロードして使いました.
ダウンロード,解凍して出来上がるLeafletフォルダ以下のファイルを,wwwroot以下にコピーします.
Drag&Dropで投げ込んでも良いですし,wwwrootで「右クリック」−「既存の項目を追加」どちらでもOKです.wwwrootは,Blazor Serverアプリでwebサーバがアクセスするトップディレクトリになります.もちろん,LeafletはダウンロードせずにCDNでアクセスでも良いです.
Blazor側の設定
まずは,「_Layout.cshtml」にLeaflet用のcssやjavascriptの設定を追加します.
<head>……</head>の部分に以下を追加します.
<link href="leaflet/leaflet.css" rel="stylesheet" >
<script src="_content/BlazorLeaflet/leafletBlazorInterops.js"></script>
<body>…..</body>の中に以下を追加します.
<script src="leaflet/leaflet.js"></script>
_Layout.cshtml全体は以下のようになります.15-16行目,34行目が追加した部分になります.
@using Microsoft.AspNetCore.Components.Web
@namespace testLeaflet.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="~/" />
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
<link href="css/site.css" rel="stylesheet" />
<link href="testLeaflet.styles.css" rel="stylesheet" />
<link href="leaflet/leaflet.css" rel="stylesheet" >
<script src="_content/BlazorLeaflet/leafletBlazorInterops.js"></script>
<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
</head>
<body>
@RenderBody()
<div id="blazor-error-ui">
<environment include="Staging,Production">
An error has occurred. This application may no longer respond until reloaded.
</environment>
<environment include="Development">
An unhandled exception has occurred. See browser dev tools for details.
</environment>
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>
<script src="leaflet/leaflet.js"></script>
<script src="_framework/blazor.server.js"></script>
</body>
</html>
次に,手抜きして,始めに表示される画面「index.razor」に地図を表示するようにします.
1,7-10行目は始めからテンプレートとして入っている部分で,その他は新たに加えた箇所になります.
@page "/"
@using System.Drawing
@using BlazorLeaflet
@using BlazorLeaflet.Models
@inject IJSRuntime jsRuntime
<PageTitle>Index</PageTitle>
<h1>Hello, world!</h1>
Welcome to your new app.
<SurveyPrompt Title="How is Blazor working for you?" />
<div style="height: 800px; width: 800px;">
<LeafletMap Map="_map" />
</div>
@code
{
private Map _map;
private LatLng _startAt = new LatLng(35.0f, 135.0f);
protected override void OnInitialized()
{
_map = new Map(jsRuntime)
{
Center = _startAt,
Zoom = 4.8f
};
_map.OnInitialized += () =>
{
_map.AddLayer(new TileLayer
{
UrlTemplate = "https://a.tile.openstreetmap.org/{z}/{x}/{y}.png",
Attribution = "© <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors",
});
};
}
}
12-14行目で,地図を入れるスペースを作っています.16-38行目が実際に地図表示するコード部分です.
ここまでで実行すると,北緯35度,東経135度を中心にして,Open Street Mapで表示されます.
地図を変更する
例えば,index.razorの33行目を以下のように変更すると,地理院タイルになります.
UrlTemplate = "https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png",
マーカーを表示する
以下のような感じでマーカ表示が出来ます.
27-33行目でマーカーを作って,42行目でレイヤーにaddしています.popupやtooltipの表示,マーカーのドラッグ等も設定できます.
@page "/"
@using System.Drawing
@using BlazorLeaflet
@using BlazorLeaflet.Models
@inject IJSRuntime jsRuntime
<PageTitle>Index</PageTitle>
<div style="height: 800px; width: 800px;">
<LeafletMap Map="_map" />
</div>
@code
{
private Map _map;
private LatLng _startAt = new LatLng(35.0f, 135.0f);
private LatLng _markerLatLng = new LatLng(35.0f, 135.0f);
protected override void OnInitialized()
{
_map = new Map(jsRuntime)
{
Center = _startAt,
Zoom = 11f
};
var marker = new Marker(new LatLng { Lat = _markerLatLng.Lat, Lng = _markerLatLng.Lng })
{
Draggable = true,
Title = "Marker 1",
Popup = new Popup { Content = string.Format("I am at {0:0.00}° lat, {1:0.00}° lng", _markerLatLng.Lat, _markerLatLng.Lng) },
Tooltip = new Tooltip { Content = "Click and drag to move me" },
};
_map.OnInitialized += () =>
{
_map.AddLayer(new TileLayer
{
UrlTemplate = "https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png",
Attribution = "© <a href=\"https://maps.gsi.go.jp/development/ichiran.html\">地理院タイル</a>",
});
_map.AddLayer(marker);
};
}
}
マーカーのアイコンを変更する
以下のようにアイコンを設定して,Markerのオプションで指定すれば,オリジナルのアイコンも利用可能です.
var icon = new Icon()
{
Url = "plane.png",
};
var marker = new Marker(new LatLng { Lat = _markerLatLng.Lat, Lng = _markerLatLng.Lng })
{
Icon = icon
};
その他,使用例
その他,ポリゴンを描いたり,画像をオーバーレイしたり,よく使われる機能は大体用意されているようです.これとは別に,もう一つおすすめのwrapperがありますので,改めて紹介したいと思います.
以下は,BlazorでFlightrader24のデータ(CSV)を表示して作ってみた動画です.描画の更新に改善の余地ありです...