GoogleAPIを利用して、住所から緯度経度を得る関数を作ろうとしています。

下記のようなコードの場合、geocoder.getLatLngが非同期なため、[3]→[1]→[2]の順で実行され、[2]以外のresult['lat']/result['lng']は、undefinedになってしまいます。
この非同期メソッドを上手くフォローした関数にするにはどうすれば良いでしょうか?
(www.geocoding.jpのようなASPもあるようですが、なるべく自前で作りたいため)
result = add2latlng("渋谷区1-1");
alert( "[1]address:" + result['address'] + "/lat:" + result['lat'] + "/lng:" + result['lng'] );

function add2latlng( address ) {
var result = new Array();
geocoder = new GClientGeocoder();
geocoder.getLatLng(address,
function(point) {
result["lat"] = point.lat();
result["lng"] = point.lng();
alert( "[2]address:" + address + "/lat:" + result['lat'] + "/lng:" + result['lng'] );
}
);
result['address'] = address;
alert( "[3]address:" + address + "/lat:" + result['lat'] + "/lng:" + result['lng'] );
return result;
}

回答の条件
  • URL必須
  • 1人2回まで
  • 登録:2007/11/05 11:20:37
  • 終了:2007/11/12 11:25:03

回答(4件)

id:takonixi No.1

takonixi回答回数7ベストアンサー獲得回数22007/11/05 20:19:47

ポイント23pt

非同期の処理を同期に変えることはできないかと思いますので

下記のように実行処理の部分を引数で与える形にしてはどうでしょうか?


function add2latlng( address , func ) {

  geocoder = new GClientGeocoder();

  geocoder.getLatLng(address,

    function(point) {

      var result = {};

      result["lat"] = point.lat();

      result["lng"] = point.lng();

      alert( "[2]address:" + address + "/lat:" + result['lat'] + "/lng:" + result['lng'] );

      result['address'] = address;

      alert( "[3]address:" + address + "/lat:" + result['lat'] + "/lng:" + result['lng'] );

      func(result);

    }

  );

}


result = add2latlng(

  "渋谷区1-1",

  function(result){

    //実行する処理

    alert( "[1]address:" + result['address'] + "/lat:" + result['lat'] + "/lng:" + result['lng'] );

  }

);

URLはダミーです

http://q.hatena.ne.jp/

id:P-mako

(XML)HttpRequestオブジェクトのようにreadyStateのような状態監視ができれば良いなぁと思っていたのですが、コールバックハンドラ形式でも工夫次第で解決できるかも知れないですね。

でも、複数の住所を緯度経度に変換して取得したいので、もう少しスマートな方法があればよいんですが・・・

もしくは、上記の下から7行目の result = add2latlng( で、resultに取得できてしまうんでしょうか?

私の知識では意味の無い戻り値だと感じますが・・・

今試せる環境にないので、後で試してみます。

2007/11/05 23:31:53
id:ardarim No.2

ardarim回答回数892ベストアンサー獲得回数1422007/11/06 00:04:28

ポイント23pt

最後の部分を

result['address'] = address;
while(result['lat'] == undefined && result['lng'] == undefined);
alert( "[3]address:" + address + "/lat:" + result['lat'] + "/lng:" + result['lng'] );
return result;

でどうでしょうか?

非同期からの結果が入るのを待つ感じです。

これで[2]->[3]->[1]の順序になって、3つとも期待通りの値が入ると思います。


urlはダミー

http://q.hatena.ne.jp/1194229236

id:takonixi No.3

takonixi回答回数7ベストアンサー獲得回数22007/11/06 01:00:38

ポイント22pt

すいません 上記のは確かにresultにはreturnしないのではいりませんね

複数でしたら下記のような感じではどうでしょうか?


var add2latlng = function(address, func){

    var geocoder = new GClientGeocoder();

    //全部の処理を終えたか確認

    //終えていればfuncを実行

    var execute = function(){

        for(var i = 0;i < address.length;i++){

            if( !address[i].complete ){

                return ;

            }

        }

        func(address);

    }

    //一つ分取得しexecute実行

    var getLatLng = function(index){

        geocoder.getLatLng(

            address[index]["address"],

            function(point) {

                address[index]["lat"] = point.lat();

                address[index]["lng"] = point.lng();

                address[index].complete = true;        //取得フラグ

                execute();

            }

        );

    }

    //各addressのlat,lng取得関数呼び出し

    for(var i = 0;i < address.length;i++){

        //取得フラグ

        address[i].complete = false;

        //各都道府県データ取得

        getLatLng(i);

    }

};

new add2latlng(

    //形式は{"address":"渋谷区1-1"}の配列形式

    [{"address":"渋谷区1-1"},{"address":"渋谷区2-4"},{"address":"渋谷区3-6"}],

    //実行処理

    function(result){

        for(var i = 0;i < result.length;i++){

            alert( "["+i+"]address:" + result[i]['address'] + "/lat:" + result[i]['lat'] + "/lng:" + result[i]['lng'] );

        }

    }

);


ダミーURLです

http://q.hatena.ne.jp/

id:lunlumo No.4

lunlumo回答回数107ベストアンサー獲得回数142007/11/07 00:46:42

ポイント22pt

 この変換処理はWebServiceでも公開されているので,サーバサイドで問い合わせて返す処理を用意すれば比較的簡単に同期処理が書けます。コールバック処理でモデルを更新して,モデルからビューに更新を通知すると言った形で処理した方が素直かとは思いますが。

http://code.google.com/apis/maps/documentation/services.html#Geo...

var	proxyUrl = "/cgi-bin/google/maps/proxy.cgi";

function add2latlng(address) {
	var	request = new GXmlHttp.create();
	var	response;
	var	result = new Array();
	
	request.open("GET", proxyUrl + "?q=" + encodeURI(address), false);
	request.send(null);
	response = eval("(" + request.responseText + ")");
	
	for (var i = 0;i < response["Placemark"].length;i++) {
		var	coordinates	= response["Placemark"][i]["Point"]["coordinates"];
		result.push({"lat":coordinates[0],"lng":coordinates[1]});
	}
	
	return result;
}

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません