匿名質問者

Google Maps Api を利用したwebアプリケーションでJavaScriptの実行結果が思う通りになりません。

マップをクリックすると逆ジオコーディングを行い、div要素内に地名を表示したいのですが、一度目のクリックでは地名が表示されず2回目以降のクリックで地名が表示されてしまいます。
これを解決するにはどうすればよいでしょうか?また一度目のクリックでグローバル変数labelがundefinedになってしまう要因をお教えいただけると幸いです。
jQueryは1.9.1を利用しています。

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2014/07/10 18:11:18
匿名質問者

質問者から

匿名質問者2014/07/10 01:28:49

html部分

<!DOCTYPE HTML>
<html>
<head>
	<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
	<script type="text/javascript" src="app.js"></script>
	<script type="text/javascript">
		$(function() {
			initialize();
		});
	</script>
</head>
<body>
<div class="main">
	<div id="map_canvas"></div>
	<div class="navi"></div>
</div>
</body>
</html>

app.js部分

var map;
var myMarker;
var geocoder;
var label;

//マップの初期化
function initialize() {
	var lat = 緯度;
	var lng = 経度;
	var latlng = new google.maps.LatLng(lat, lng);
	var mapOptions = {
		zoom: 15,
		center: latlng,
		mapTypeId: google.maps.MapTypeId.ROADMAP
	};

	map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);

	myMarker = createMarker({
		position: latlng,
		map: map,
		title: '現在地'
	});

	google.maps.event.addListener(map, 'click', function(e) {
		myMarker.setOptions({
			position: e.latLng
		});
		map.panTo(e.latLng);

		reverseGeocoder(e.latLng);
		changeLabel();
	});
}

//マーカーの作成
function createMarker(opts) {
	var marker = new google.maps.Marker(opts);
	return marker;
}

//逆ジオコーディング
function reverseGeocoder(latlng) {
	geocoder = new google.maps.Geocoder();

	geocoder.geocode({'latLng': latlng}, function(results, status) {
		if (status == google.maps.GeocoderStatus.OK) {
			label = results[0].formatted_address;
		} else {
			alert('エラー');
		}
	});
}

//div要素書き換え
function changeLabel() {
	$('.navi').html(label);
}

補足

ユーザー定義関数reverseGeocoder()でグローバル変数labelに結果を代入し、ユーザー定義関数changeLabel()でDOMを操作してdiv要素のテキストを書き換えたいのですが、この処理がうまくいっていないようです。

試しにユーザー定義関数initialize()のイベントリスナーに渡すコールバックにconsol.log()を一行加え

reverseGeocoder(e.latLng);
console.log(label);
changeLabel(label);

としchangeLabel()の実行前に変数labelをdumpしてみると一度目のクリック時にはundefinedが返ってきました。

ジオコーディング関数に渡すコールバックの結果処理部分にconsol.log()を加え

geocoder.geocode({'latLng': latlng}, function(results, status) {
	if (status == google.maps.GeocoderStatus.OK) {
		label = results[0].formatted_address;
		console.log(label);
	} else {
		alert('エラー');
	}
});

とすると一度目のクリックで結果が取得できているようで、changeLabel()関数を利用せずreverseGeocoder()のなかでlabel変数に代入した直後にDOMを操作すれば上手くいきましたが、出来れば逆ジオコーディング関数とDOM操作関数とを分けて利用したいです。

ベストアンサー

匿名回答1号 No.1

ジオコーディング サービスへのアクセスは、Google Maps API が外部サーバーへの呼び出しを行う必要があるため、非同期に行われます。このため、コールバック メソッドを渡してリクエストの完了時に実行する必要があります。このコールバック メソッドによって結果が処理されます。ジオコーダは、複数の結果を返すことがあります。
 

ジオコーディング サービス - Google Maps JavaScript API v3 — Google Developers

その他の回答0件)

匿名回答1号 No.1

ここでベストアンサー

ジオコーディング サービスへのアクセスは、Google Maps API が外部サーバーへの呼び出しを行う必要があるため、非同期に行われます。このため、コールバック メソッドを渡してリクエストの完了時に実行する必要があります。このコールバック メソッドによって結果が処理されます。ジオコーダは、複数の結果を返すことがあります。
 

ジオコーディング サービス - Google Maps JavaScript API v3 — Google Developers

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

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

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

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

回答リクエストを送信したユーザーはいません