第11回 都道府県のセレクトボックスを現在地に近い順にソートする(Firefox 3.5のGeolocation API) – jQuery入門

2009 年 7 月 16 日 投稿者: naga3

都道府県を選択するセレクトボックスって良く使いますよね。
最近は親切なのかどうか分かりませんが、東京が選択エリアの一番上に来てたりして、地方の人には辛い時代です。ちゃんとした県の並びとしては、JIS X0402に準拠するのが良さそうです。都道府県選択するやつ が参考になりました。

で、本題なのですが、Firefox 3.5 からは位置情報通知機能(Geolocation API)がサポートされています。ならば現在いる場所から近い順に県を表示してあげれば親切ではないのか?と思いサンプルを作ってみました。jQuery入門というタイトルからは逸脱していてすみません。

位置情報取得のコーディングについては、「Firefox 3.5の位置情報通知機能の仕組みとサンプル – F.Ko-Jiの「一秒後は未来」」さんのページがとても分かりやすかったので参考にさせて頂きました。

実行サンプル

Firefox 3.5以上対応です。位置情報を求めてきます的なメッセージが出たら許可してあげてください。

ソース

ファイルが必要ならば右クリックで保存してください。
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">google.load("jquery", "1.3");</script>
<script type="text/javascript">
$(function() {
    var prefs = [
        ['北海道', 43.03, 141.21],
        ['青森県', 40.49, 140.44],
        ['岩手県', 39.42, 141.09],
        ['宮城県', 38.16, 140.52],
        ['秋田県', 39.43, 140.06],
        ['山形県', 38.15, 140.20],
        ['福島県', 37.45, 140.28],
        ['茨城県', 36.22, 140.28],
        ['栃木県', 36.33, 139.53],
        ['群馬県', 36.23, 139.03],
        ['埼玉県', 35.51, 139.38],
        ['千葉県', 35.36, 140.06],
        ['東京都', 35.41, 139.45],
        ['神奈川県', 35.26, 139.38],
        ['新潟県', 37.55, 139.02],
        ['富山県', 36.41, 137.13],
        ['石川県', 36.33, 136.39],
        ['福井県', 36.03, 136.13],
        ['山梨県', 35.39, 138.34],
        ['長野県', 36.39, 138.11],
        ['岐阜県', 35.25, 136.45],
        ['静岡県', 34.58, 138.23],
        ['愛知県', 35.11, 136.54],
        ['三重県', 34.43, 136.30],
        ['滋賀県', 35.00, 135.52],
        ['京都府', 35.00, 135.46],
        ['大阪府', 34.41, 135.29],
        ['兵庫県', 34.41, 135.11],
        ['奈良県', 34.41, 135.48],
        ['和歌山県', 34.14, 135.10],
        ['鳥取県', 35.29, 134.13],
        ['島根県', 35.27, 133.04],
        ['岡山県', 34.39, 133.54],
        ['広島県', 34.23, 132.27],
        ['山口県', 34.11, 131.27],
        ['徳島県', 34.03, 134.32],
        ['香川県', 34.20, 134.02],
        ['愛媛県', 33.50, 132.44],
        ['高知県', 33.33, 133.31],
        ['福岡県', 33.35, 130.23],
        ['佐賀県', 33.16, 130.16],
        ['長崎県', 32.45, 129.52],
        ['熊本県', 32.48, 130.42],
        ['大分県', 33.14, 131.37],
        ['宮崎県', 31.56, 131.25],
        ['鹿児島県', 31.36, 130.33],
        ['沖縄県', 26.13, 127.41]
    ];

    navigator.geolocation.getCurrentPosition(function(pos) {
        var lat = pos.coords.latitude;
        var long = pos.coords.longitude;
        $.each(prefs, function(i, p) {
            p[3] = (lat - p[1]) * (lat - p[1]) + (long - p[2]) * (long - p[2]);
        });
        prefs.sort(function(p1, p2) {
            return p1[3] - p2[3];
        });
        $.each(prefs, function(i, p) {
            $('<option></option>').html(p[0]).appendTo('#pref');
        });
    }, function() {
        $('#msg').html('場所を特定できません。');
    });
});
</script>

</head>
<body>
<select id="pref"></select>
<span id="msg"></span>
</body>
</html>
ほとんど県の位置定義部分なので、実際のコードは10行ちょっとのシンプルさです。

プログラムの解説

県の位置定義

var prefs = [
    ['北海道', 43.03, 141.21],
    ['青森県', 40.49, 140.44],
・・・・・・
県の位置を配列として定義している部分です。県の中心位置をどこに設定するか悩みましたが、今回は単純に県庁所在地の場所、ということにしました。最初の数字が県庁所在地の緯度、2番目の数字が経度です。

現在位置を取得

navigator.geolocation.getCurrentPosition(function(pos) {・・・}, function() {・・・});
現在位置を取得するFirefox 3.5のメソッドです。Geolocation APIという標準に準拠していれば、他のブラウザでも動くそうです。最初の引数が位置取得に成功したとき、2番目の引数が位置取得に失敗したときにそれぞれ呼び出されるコールバック関数です。成功したときには引数で位置情報が帰ってきます。その構造は「Firefox 3.5の位置情報通知機能の仕組みとサンプル – F.Ko-Jiの「一秒後は未来」」さんを見ると詳しく書かれていますが、coords.latitude に緯度、coords.longitudeに経度が入ります。

現在位置と各県庁所在地との距離を求める

var lat = pos.coords.latitude;
var long = pos.coords.longitude;
$.each(prefs, function(i, p) {
    p[3] = (lat - p[1]) * (lat - p[1]) + (long - p[2]) * (long - p[2]);
});
pref配列の各要素の最後に、現在位置と各県庁所在地との距離の二乗を格納しています。緯度と経度から距離を正確に計算するには難しい計算式があるのですが、今回は正確に求める必要もないので、単純に平面座標と見なしてピタゴラスの定理を使って計算しています。

現在位置から近い順にソート

prefs.sort(function(p1, p2) {
    return p1[3] - p2[3];
});
JavaScriptだと、とてもシンプルに書けます。

セレクトボックスにソートされた配列要素を追加

$.each(prefs, function(i, p) {
    $('<option></option>').html(p[0]).appendTo('#pref');
});
今回唯一jQueryっぽい部分です。空のoptionタグを作って、要素のテキストとして県名(p[0])を追加し、IDがprefのセレクトボックスの子要素として追加しています。

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

コメントをどうぞ