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


この記事へのトラックバックURL

この記事へのコメント
こんにちは.
掲載頂いたHTML/スクリプトで,GPSから位置を取得してGoogleMapへの現在位置表示に成功しました.

機種:
 SONY VAIO X (ノートPC)
OS:
 Windows 7 Professional
GPS:
 本体内蔵,NMEA書式でCOMポートとして見えるもの
ドライバ:
 http://www.turboirc.com/gps7/ のCOMポートNMEA用汎用センサドライバ

"VAIOアプリ"無しで買ったので,そのままだと"Location Search"とかの意味不明なソフトウェアが仲介したりしますが,そういうのは無しの環境です.
..ので,他のCOMポートとして見えるNMEAでも,上記の汎用ドライバをインストールすれば,同じことをやれるのではないかと思います.


GPS内蔵で買って,やりたかったことはまさしくこれだったので,とてもありがたいスクリプトです.

以上,お礼がてら報告まで.
Posted by storm at 2010年11月05日 23:21
返事が遅くなり申し訳ございません.

検証ありがとうございます!期待通りに動作するようで安心しました.お役立て頂いたようで何よりです.

ここ1年でGPSを取り巻く状況は大分変わったようですね.精度の良し悪しはともかく,GPSが無くとも「Geosense for Windows」というGPSの機能をエミュレートするソフトを導入しても動作するようです.
Posted by mksaver70 at 2010年11月13日 10:09
検索ロボットや迷惑メールbot等が常に巡回しています.情報は慎重に記入してください.メール,URLは無記入でも投稿できます.スパムよけの為,国外からの書き込みは,国内IP Proxyをご利用下さい.