/**
* @filename geolocator_ui.js
* @charset utf-8
* @modified September 10, 2010
* @description GeoLocatorV3 UI 制御用
*
* COPYRIGHT (C) 2007-2010 BLADES CO.,LTD. ALL RIGHTS RESERVED.
*
* This program is free software; you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License (http://www.gnu.org/) for more details.
*/
(function(){
var init = function(){
var win = this,
doc = win.document,
bdy = doc.body,
ns = win.blades,
$ = ns.$,
$$ = ns.$$,
APP_ID = "bladesGeoLocator",
//グローバル関数
parseInt = win.parseInt,
//ブラウザ判別
isIE = doc.all && !win.opera,
//定数
DEFAULT_VALUE = "Search by address",
//正規表現
rgxIsNum = /^[-+]?\d*(?:\.\d*)?$/,
//位置取得用
ng = navigator.geolocation,
//各種値格納用
zoom = 2,
lat = 0,
lng = 0,
ll,
//GoogleMapsAPI
gm = google.maps,
gevt = gm.event,
GLL = gm.LatLng,
gmap = new gm.Map( $("map")(), {
zoom : zoom,
center : new GLL(lat, lng),
mapTypeId : gm.MapTypeId.ROADMAP,
navigationControl : false,
mapTypeControl : true,
mapTypeControlOptions : {
style : gm.MapTypeControlStyle.DROPDOWN_MENU
},
scaleControl : true,
scaleControlOptions : {
position : gm.ControlPosition.TOP_LEFT
}
}),
gcdr = new gm.Geocoder(),
//DOM操作用
$bdy = $(bdy),
$zoom = $("zoom")(),
$pos = $("pos")(),
$fQueryWrapper = $("fQueryWrapper"),
$fQuery = $("fQuery").on("blur", function(evt, elm){
this.cls("-focus");
}).on("focus", function(){
this.cls("+focus");
})(function(elm){
elm.value = "";
elm.focus();//開いた元のページのフォーカスを解除
elm.blur();
}),
fQuery = $fQuery(),
$btnSearch = $("btnSearch"),
$fZoom = $("fZoom"),
$fLng = $("fLng"),
$fLat = $("fLat"),
$$f = $$([ $fZoom, $fLng, $fLat ]);
/**
* 地図の中心を現在地に設定
*/
/*
ng && ng.getCurrentPosition(function(pos) {
var ll = pos.coords;
gmap.setZoom( 10 );
gmap.panTo( new GLL(ll.latitude, ll.longitude) );
});
*/
/**
* 中心の緯度・経度を表示
*/
gevt.addListener(gmap, "center_changed", function move(){
var FXD = 10,//偶数のみ
ctr = gmap.getCenter(),
val = /*win.name = */( lat = ctr.lat().toFixed(FXD) ) + "," + ( lng = ctr.lng().toFixed(FXD) );
$pos.innerHTML = '
' +
val.
replace(/(\d\d|\d)/g, '
').
replace(/-/g, '
').
replace(/\./g, '
').
replace(",", '
')
+ '
';
return move;
}());
/**
* 各種デジタル表示
*/
//拡大率
$fZoom.on("focus", function(evt, elm){
elm.value = zoom;
});
$("fZoomWrapper").on("submit", function(){
var val = $fZoom().value;
rgxIsNum.test(val) && gmap.setZoom( parseInt( $fZoom().value, 10 ) );
$fZoom("blur");
return false;
});
//緯度
$fLat.on("focus", function(evt, elm){
elm.value = lat;
});
$("fLatWrapper").on("submit", function(){
var val = $fLat().value;
rgxIsNum.test(val) && ( gmap.panTo( new GLL(val, lng) ), resetLatLng() );
$fLat("blur");
return false;
});
//経度
$fLng.on("focus", function(evt, elm){
elm.value = lng;
});
$("fLngWrapper").on("submit", function(){
var val = $fLng().value;
rgxIsNum.test(val) && ( gmap.panTo( new GLL(lat, val) ), resetLatLng() );
$fLng("blur");
return false;
});
//各種入力フィールド
$$f.on("blur", function(evt, elm){
this.cls("-focus");
elm.value = "";
}).on("focus", function(){
this.cls("+focus");
}).on("click", function(evt){
evt.stopPropagation();
})(function(elm){
elm.value = "";
});
$(doc).on("click", function(){
$$f("blur");
});
var resetLatLng = function(){
//alert("reset ll");
ll = null;
};
/**
* 拡大率表示
*/
gevt.addListener(gmap, "zoom_changed", function zoomend(){
var z = zoom = gmap.getZoom();
$zoom.innerHTML = '';
if(ll){
//alert("誤差修正 ll= " + ll.lat() + "," + ll.lng());
gmap.setCenter( ll );//拡大率を上げた時の誤差を修正
}
return zoomend;
}());
gevt.addListener(gmap, "dragend", resetLatLng);
$("btnPlus").on("click", function(){
var MAX = 20,
z = zoom;
gmap.setZoom( zoom = z === MAX ? z : ++z );
return false;
});
$("btnMinus").on("click", function(){
var z = zoom;
gmap.setZoom( zoom = z === 0 ? z : --z );
return false;
});
/**
* 住所検索
*/
var search = function(evt){
var q = fQuery.value;
/*
/\S/.test(q) && q !== DEFAULT_VALUE && gcdr.getLatLng(q, function(ctr){
gmap.panTo(ll = ctr);//住所検索時拡大率が低い(=緯度・経度の分解能が低い)とその後拡大した際に誤差が生じる。それを補正するため正確な値を保持しておく
});
*/
/\S/.test(q) && q !== DEFAULT_VALUE && gcdr.geocode( { "address" : q }, function(res, stat) {
if( stat === gm.GeocoderStatus.OK ){
gmap.setCenter(res[0].geometry.location);
}else{
//alert( "ERROR : " + stat );
}
});
return false;
};
search();
$fQueryWrapper.on("submit", search);
$btnSearch.on("click", search);
$fQuery.on("focus", function(){
fQuery.value === DEFAULT_VALUE && ( fQuery.value = "" );
$fQueryWrapper.cls("+focus");
}).on("blur", function fQueryBlur(){
/\S/.test(fQuery.value) || ( fQuery.value = DEFAULT_VALUE );
$fQueryWrapper.cls("-focus");
return fQueryBlur;
}());
/**
* 現在地表示
*/
/*
gevt.addListener(gmap, "idle", function(){
gcdr.geocode( { "location" : gmap.getCenter() }, function(res, stat) {
if( stat === gm.GeocoderStatus.OK ){
var adr = res[0].formatted_address,
zip = "",
rgx = /(〒\d{3}\-\d{4})/;
if( !rgx.test(adr) ){//郵便番号を補完
for(var i=1, m, len=res.length; i