Windows7のGPSセンサー(Location API)とGoogle Mapsを利用して今いる居場所を割り当てる(未検証)

Ubuntu 9.10とWindows 7が登場してOSいじくりが満足にできてうれしい毎日ですがみなさんいかがでしょうか。自分もWindows7 Pro UPG版を購入して、Ubuntuもマウスが効かないバグにはまりながらもようやくKarmicにアップデートいたしました。特にWindows 7については追加された機能が豊富すぎて訳分からん状態なのです。あとで自分なりにまとめたいですねえ。

Windows 7が提供する新機能の一つに「Location API」というものがあります。Windows ガジェットの「天気」にも、Location APIが使われている形跡が見られ、位置を自動的に検出するオプションがあるようです。GPSを持っていれば、移動中に自分が今いる場所の天気を表示できるというわけです。

位置を自動的に検出するオプション
こんなやつ。GPSは持ってないので恩恵は受けられないのですが…

このLocation APIをJavaScript(JScript)を利用して、GPSから緯度経度を抽出し、最終的にGoogle Mapsを呼び出して自分のいる場所を割り当てるサンプルを作ってみました。ただし、自分はGPSを持っていないのでどうなるかは分かりませんが、抽出された緯度、経度がNumber型であることを仮定した上で作成してしています。

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">

function loc_get(name0, name1)
{
	var loc0 = document.getElementById(name0);
	var loc1 = document.getElementById(name1);
	var list = [];

	list[list.length] = {};
	list[list.length-1].name = "緯度";
	try { list[list.length-1].value = loc0.LatLongReport.Latitude; }
	catch(e) { list[list.length-1].value = "測定できません"; }

	list[list.length] = {};
	list[list.length-1].name = "経度";
	try { list[list.length-1].value = loc0.LatLongReport.Longitude; }
	catch(e) { list[list.length-1].value = "測定できません"; }

	list[list.length] = {};
	list[list.length-1].name = "住所1";
	try { list[list.length-1].value = loc1.CivicAddressReport.AddressLine1;
	if(list[list.length-1].value == "") list[list.length-1].value = "測定できません"; }
	catch(e) { list[list.length-1].value = "測定できません"; }
	
	list[list.length] = {};
	list[list.length-1].name = "住所2";
	try { list[list.length-1].value = loc1.CivicAddressReport.AddressLine2;
	if(list[list.length-1].value == "") list[list.length-1].value = "測定できません"; }
	catch(e) { list[list.length-1].value = "測定できません"; }

	list[list.length] = {};
	list[list.length-1].name = "国";
	try { list[list.length-1].value = loc1.CivicAddressReport.CountryRegion;
	if(list[list.length-1].value == "") list[list.length-1].value = "測定できません"; }
	catch(e) { list[list.length-1].value = "測定できません"; }

	list[list.length] = {};
	list[list.length-1].name = "都道府県";
	try { list[list.length-1].value = loc1.CivicAddressReport.StateProvince;
	if(list[list.length-1].value == "") list[list.length-1].value = "測定できません"; }
	catch(e) { list[list.length-1].value = "測定できません"; }

	list[list.length] = {};
	list[list.length-1].name = "市町村";
	try { list[list.length-1].value = loc1.CivicAddressReport.City;
	if(list[list.length-1].value == "") list[list.length-1].value = "測定できません"; }
	catch(e) { list[list.length-1].value = "測定できません"; }

	list[list.length] = {};
	list[list.length-1].name = "郵便番号";
	try { list[list.length-1].value = loc1.CivicAddressReport.PostalCode;
	if(list[list.length-1].value == "") list[list.length-1].value = "測定できません"; }
	catch(e) { list[list.length-1].value = "測定できません"; }

	return list;
}

function init(name0, name1, name2, name3)
{
	if(!('\v'=='v')) {
		alert("IEじゃないと動きません。");
		return;
	}

	var loc0 = document.getElementById(name0);

	if(typeof(loc0.Status)=="undefined") {
		alert("Windows 7以降じゃないと動きません。");
		return;
	}

	switch(loc0.Status) {
		case 1:	
			alert("エラーが発生しました。");
			return;
		case 2:
			alert("アクセスは拒否されました。");
			return;
		case 3:
			alert("しばらく待ってから、もう一度押してください。");
			return;
		case 0:
			if(!confirm("サポートしてないようですが、ダメもとで測定してみますか?"))
			return;
		case 4:
			break;
		default:
			alert("この雰囲気…もしや新しいAPIかっ!?");
			return;
	}

	var list = loc_get(name0, name1);
	var str = "";
	var Lat;
	var Long;
	
	// 取得したものをHTMLに戻す
	for (i = 0, j = list.length; i < j; i++) {
		str += list[i].name + ": " + list[i].value + "<br>";
		if (list[i].name == "緯度") Lat = list[i].value;
		if (list[i].name == "経度") Long = list[i].value;
	}

	try { document.getElementById(name2).innerHTML = str; }
	catch(e) { alert(str.replace(/<br>/g,"\n")); }

	if(typeof(Lat) == "number" && typeof(Long) == "number") {
		document.getElementById(name3).src =
		"http://maps.google.com/maps?q=" + Lat + "," + Long +
		"&z=14&iwloc=near&output=embed";
		document.getElementById(name3).style.display = "";
	}

	return true;
}

</script>
</head>
<body>
<form>
<input type="button" onclick="init('loc0','loc1','div0','iframe0')" value="計測">
</form>
<!-- 緯度経度を調べるためのオブジェクト -->
<object id="loc0" width="0" height="0"
 classid="clsid:9DCC3CC8-8609-4863-BAD4-03601F4C65E8"></object>
<!-- 都道府県市町村を調べるためのオブジェクト -->
<object id="loc1" width="0" heihgt="0"
 classid="clsid:2A11F42C-3E81-4AD4-9CBE-45579D89671A"></object>

<!-- 表示に関わるもの -->
<div id="div0"></div>
<iframe id="iframe0" width="640" height="480" src="about:blank" style="display:none"></iframe>
</body>
</html>

動作条件として、Windows 7以降であること(多分)、要ActiveXなのでIEを使って動作させていること、そして、GPSを持っていること(自分は持ってないので検証できないという罠w)。GPSが無くてもWindows 7以降であれば強制的に動作させることも可能です。ただ、GPSがないと「国」だけしか分からないようです。

.html(できれば.htaで)を保存して、IEを立ち上げ、計測ボタンを押すとAPIが動作し、Google Mapsの矢印が表示されるという流れになっています。loc0.Statusが4になればGPSがあっても無くても準備はできたと判断できます。

緯度経度がどのようにWindowsから返されるのかが分からないです。多分Numberで返ってくるだろうと思いますが、0以上のNumberなら動く可能性が高いです。動作検証は自己責任でお願いします…

成功イメージ
うまくいけばこんな感じで動いてくれると思います

(2009.11.10)Sensor APIじゃなくてLocation APIの間違いだったので書き直し。詳しくはここを参照。
http://msdn.microsoft.com/en-us/library/dd464636(VS.85).aspx