blazorからgeolocation APIを使ってみる

HTML5をサポートしているブラウザでは、GPS等を使用して、位置情報を得る、geolocation APIを使用することが可能である。

geolocation APIには以下のような関数が用意されている。

geolocation.getCurrentPosition-位置情報を1回だけ取得する。

//
//	loc:位置情報
//	err:エラー情報
//
navigator.geolocation.getCurrentPosition(
    function(loc) {}	// 位置情報取得成功時処理
    function(err) {}	// 位置情報取得失敗時処理
);

geolocation.geolocation.watchPosition-位置情報が変わるたびに指定関数を呼び出す。

//
//	loc:位置情報
//	err:エラー情報
//
watchid = navigator.geolocation.watchPosition(
    function(e) {},		// 位置情報取得成功時処理
    function(e) {}		// 位置情報取得失敗時処理
);

geolocation.clearWatch-watchPositionの停止

//
//	watchid:watchPositionの戻り値
//
navigator.geolocation.clearWatch(watchid);
位置情報パラメータ
coords 位置情報
latitude緯度
longitude経度
altitude高度
accuracy緯度・経度の誤差
altitudeAccuracy高度の誤差
heading方角(0.0~360.0)
speedスピード
timestampタイムスタンプ

エラー情報パラメータ
codeエラーコード
0 不明なエラー
1 位置情報の取得を拒否された
2 位置情報を取得できない
3 タイムアウト
messageエラーメッセージ

折角このようなAPIがあるので、blazorから呼び出してみたい。ただ、getCurrentPosition関数やwatchPosition関数のコールバック関数が必要になるので、そこから、C#コードを呼び出すようにする。

var GPSLib = {
	・・・
	GetPosition : function(helper,complete,errorhandler) {
	    navigator.geolocation.getCurrentPosition(
	        function(e) {
	            // パラメータを作成(eをそのまま渡してもキャストされないので・・・)
	            var prm = {
	                coords: {
	                    latitude: e.coords.latitude,
	                    longitude: e.coords.longitude,
	                    altitude: e.coords.altitude != null ? e.coords.altitude : 0,
	                    accuracy: e.coords.accuracy != null ? e.coords.accuracy : 0,
	                    altitudeAccuracy: e.coords.altitudeAccuracy != null ? e.coords.altitude : 0,
	                    heading: e.coords.heading != null ? e.coords.heading : 0,
	                    speed: e.coords.speed != null ? e.coords.speed : 0
	                },
	                timestamp: e.timestamp
	            };
	            // C#コードの呼出し
	            helper.invokeMethodAsync(complete,prm);
	        },
	        function(e) {
	            // パラメータを作成(eをそのまま渡してもキャストされないので・・・)
	            var prm = {
					code: e.code,
					message: e.message
				};
	            // C#コードの呼出し
				helper.invokeMethodAsync(errorhandler,prm);
	        }
	    )
	},
・・・
};
// 位置情報(一応、すべてのプロパティを得られるようにした)
public class GeoInfo {
    public Coords coords { get; set; }
    public long timestamp { get; set; }
}
public class Coords {
    public double latitude {get; set;}	// 緯度
    public double longitude {get; set;}	// 経度
    public double altitude { get; set; }	// 高度
    public double accuracy	{get; set;} // 緯度・経度の誤差
    public double altitudeAccuracy {get; set;}	// 高度の誤差
    public double heading {get; set; }	// 方角(0.0~360.0)
    public double speed  { get; set; } // スピード
}
// エラー情報
public class GeoError {
	public int code { get; set; }
	public string message { get; set; }
}

// 位置情報取得完了時処理
[JSInvokable]
public async Task OnGetPositionComplete(GeoInfo e) {
    Latitude = e.coords.latitude;
    Longitude = e.coords.longitude;
    Orient = e.coords.heading;
	・・・
    this.StateHasChanged();
}

// 位置情報取得エラー時処理
[JSInvokable]
public void OnGetPositionFail(GeoError e) {
	ErrorMessage = $"位置情報取得エラー:{e.code} - {e.message}";
	this.StateHasChanged();
}

・・・
	// GetPositionの呼出し
	await JSRuntime.InvokeVoidAsync(
	    "GPSLib.GetPosition",
	    DotNetObjectReference.Create(this),
	    "OnGetPositionComplete","OnGetPositionFail");
	);

GoogleやBing等のMAP APIと組み合わせると、スマホやタブレット用に結構面白いアプリが簡単に作成できる。(歩いた場所のトレースや現在位置からスポット検索等)

イベントの発生頻度を考えると、Server Side版よりもWASM版で作成した方が良いと思われる。(保持できるデータの上限が気になるところだが・・・)

takezou について

ソフトウェア開発会社(ITと言う言葉は大嫌い)で働く、元技術者。 未だに、社内システム位は作ってますが・・・ プログラミング言語はC#が好き。
カテゴリー: asp.net core, Blazor, C#, 技術系 パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください