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版で作成した方が良いと思われる。(保持できるデータの上限が気になるところだが・・・)