/** * @name CeL map function * @fileoverview * 本檔案包含了 map 的 functions。 * @since */ 'use strict'; if (typeof CeL === 'function') CeL.run( { name:'interact.integrate.map', code : function(library_namespace) { /** * null module constructor * @class map 的 functions */ var _// JSDT:_module_ = function() { // null module constructor }; /** * for JSDT: 有 prototype 才會將之當作 Class */ _// JSDT:_module_ .prototype = { }; // init function var SL=new Debug.log,sl=function(){SL.log.apply(SL,arguments);},error=function(){SL.error.apply(SL,arguments);},warn=function(){SL.warn.apply(SL,arguments);}; var gMap,mapO,mData,lostItem,gLocal,dLoc={tw:[23.7,121]}; // 台灣: 23.7,121 addLoad(function(){ var b=SL.setBoard('log'); if(window.location.protocol=='file:'&&b)b.style.display='block'; // 強制顯示 log if(init&&init.run)sl('Page loaded. Prepare to initial..'); if(typeof GLatLng=='undefined'){sl('GMap does not loaded.');return;} for(var i in dLoc) dLoc[i]=new GLatLng(dLoc[i][0],dLoc[i][1]); setTimeout('init(0);',0); }); init.run=1; function init(i){ if(!arguments.callee.run)return; var m=0,n; switch(i){ case m++: setSize(); if(typeof preLoadMap=='function')preLoadMap(); break; case m++: catchFile.sn='map-files'; catchFile.f=function(url,success,captureId){ sl('Capture '+(success?'succeeded':'failed')+': '+url+''); }; catchFile([ 'map.js', 'map.css' ]); break; case m++: initMap(); initSearch(); if(window.location.protocol=='file:')setTimeout('mapO.removeTM();',3000); // 3000: 適当。隨 client 而有不同。 break; case m++: readLoc(); break; case m++: loadMapData(); break; case m++: placeMapItem(); break; case m++: if(typeof additionalFunc=='function')additionalFunc(); break; } m=['Starting initial process. Catch files..','Catch done. Initial all components..','Map loaded. Loading address records..','address loaded. Loading map data..','map data loaded. placing map items..','placing done. Do additional works..','Initial done.']; sl('init: '+m[i]); if(arguments.callee.run && ++i')+'
'+r.address); // http://code.google.com/apis/ajaxsearch/documentation/reference.html#_class_GlocalResult var h='
'+r.title +'
'+r.address+'
'+r.phone.join('
')+(r.phone.length?'
':'')/*+r.listingType+'
'*/+r.content+'
('+r.lat+','+r.lng+') Use Google Maps
'; if(sA2.c)sA2.c.innerHTML+=h;else sl(h); },'Local'); sl('initSearch: local search initialed.'); }}); else sl('initSearch: Cannot initial local search. Please load API.'); } var _map_tmp_message; initMap.flag={backgroundColor:'#DDE'}; function initMap(){ var a,m,i,_f=arguments.callee; mapO=new gMap('map_canvas',dLoc.tw,_f.flag); //if(!mapO)return 1; //mapO.geocoder.setBaseCountryCode('TW'); sl('initMap: set geocoder country code: '+mapO.geocoder.getBaseCountryCode()); // 要先 show 才能得到 getOverviewMap() if(m=mapO.overviewMap) // IE7 上 .hide() 時 .show() 會出錯 // 2008/9/6 22:37:33 IE6 也會出錯了 if(navigator.userAgent.indexOf('MSIE')==-1) m.show(),setOverviewMap(); // small mark template http://econym.googlepages.com/custom.htm http://mapki.com/wiki/Available_Images http://econym.googlepages.com/geicons.htm http://code.google.com/apis/maps/documentation/overlays.html#Icons_overview // iconSize 的處理還是有問題。 mapO.icon(_f.iconOption||{ shadow:'http://labs.google.com/ridefinder/images/mm_20_shadow.png', iconSize:new GSize(12,20), shadowSize:new GSize(22,20), iconAnchor:new GPoint(6,20), infoWindowAnchor:new GPoint(5,1) },1); mapO.icon(_f.iconArray||[ {image:'http://labs.google.com/ridefinder/images/mm_20_green.png'},//http://www.google.com/intl/en_us/mapfiles/ms/micons/blue-dot.png//{shadow:'http://maps.google.com/mapfiles/kml/pal5/icon14s.png',image:'http://maps.google.com/mapfiles/kml/pal5/icon14.png'},// {image:'http://labs.google.com/ridefinder/images/mm_20_yellow.png'}, {image:'http://labs.google.com/ridefinder/images/mm_20_green.png'},//{icon:G_DEFAULT_ICON}, {image:'http://labs.google.com/ridefinder/images/mm_20_orange.png'},//'http://maps.google.com/mapfiles/arrow.png', '' ]); mapO.runAfterAdd=function(o){getO.add(o.address,o.name);showML.sel(o);showML();}; mapO.runOnClick=function(o){showML.sel(o);showML();}; mapO.runAfterRemove=function(o){if(showML.sel()==o)showML.sel(null,1);showML();}; mapO.notFound=function(a,d){sl('沒找到 ['+a+'] '+d.name+'');return false;}; // 在 unload 的時候呼叫 GUnload 以避免瀏覽器 memory leak。 addListener(0,'unload',function(){try{GUnload();}catch(e){}}); a=function(htm,t,js,ico){ return '
'+htm+'
'; }; if(m=mapO.map) // use google's message i=function(i){try{ eval('_map_tmp_message=p('+i+');',m); var a=_map_tmp_message; //sl('setContextMenu '+i+': '+a); return a&&a.length<8?a:''; }catch(e){}}, mapO.setContextMenu([ a(i(10985)||'Zoom in','將地圖於此放大','mapO.showContextMenu(0),mapO.map.zoomIn(mapO.clickLatLng,true);','http://www.google.com/mapfiles/zoom-plus.png') ,a(i(10986)||'Zoom out','將地圖於此縮小','mapO.showContextMenu(0),mapO.map.zoomOut(mapO.clickLatLng,true);','http://www.google.com/mapfiles/zoom-minus.png') ,a(/*i(11047)||*/'Set Center','將地圖於此置中','mapO.showContextMenu(0),mapO.setCenter(mapO.clickLatLng);','http://www.google.com/mapfiles/center.png') ,'
' ,a('Search near','搜尋附近','mapO.showContextMenu(0),showNeighbor(mapO.clickLatLng);','http://maps.google.com/mapfiles/kml/pal2/icon13.png') ].join('')), GEvent.addListener(m,"click",function(){ mapO.showContextMenu(0); }),GEvent.addListener(m,"dragstart",function(){ mapO.showContextMenu(0); }); } function readLoc(){ if(loadMapData.dataF)catchFile([loadMapData.dataF,mapO.locFP=loadMapData.dataF+'.adr.csv']); mapO.readLoc(); } //loadMapData.baseD=''; // 預設可使用之模板 loadMapData.getHTM=function(d,type){ var l=mData[d.name||d.address],a=[mapO.getPoint(d,type)],r=[]; if(d.address||'')a.unshift(d.address); l=l?l.link:''; if(!loadMapData.baseD)loadMapData.baseD=''; if(d.name) // 不能用 this.baseD r.push(''+(l?''+d.name+'':d.name)+''); if(d.dscr)r.push(d.dscr); r.push('
'+a.join('
')+'
'); if(typeof d.getLength=='function')r.push('length: '+(d.getLength()/1000).toFixed(3)+'km'); if(typeof d.getArea=='function')r.push('面積: '+d.getArea().toFixed(3)+'m²'); //if(showNeighbor.pointer&&d.getLatLng)r.push('距離 '+showNeighbor.pointer.distanceFrom(d.getLatLng())); //r.push(,'
search near'); return r.join('
').replace(/(<\/(div|p)>)\s*/g,'$1'); }; loadMapData.lessItems=3; loadMapData.forEach=function(mapData,index){}; /* loadMapData.zIndexP=function(){ sl('click '+this.name); return -1; }; */ function loadMapData(){ /* load: 這裡假設 data 中標題可作為id(獨一無二) map data: [標題 敘述(description) link _data_] _data_: search string/kind additional description/data of different kind of data search string/additional description (用括弧框起來的) 'marker' lat lng 'polyline' points levels 'polygon' points levels mData[標題||address]={}; */ mData={}; var i=0,m,t,_f=arguments.callee; _f.run=1; try{t=getU(_f.dataF);}catch(e){sl('Get data file ['+_f.dataF+'] error: '+e.message);} if(t)t=parseCSV(t);//t.replace(/\r+/g,'').replace(/\n+$/,'').replace(/^\n+/,'').split('\n'); else t=[],showML.write('No list got of ['+_f.dataF+'].'); showML.write('總共 '+t.length+' 筆資料正處理中,請稍候…'); sl('loadMapData: Found '+t.length+' lines. Parsing.. (stop)'); for(;i').split('\t')).length>_f.lessItems) if(t[i].length>_f.lessItems) _f.forEach(t[i],i); } _f.run=0; } placeMapItem.done=function(i){ //sl('placing done.'); showML.refresh=1,showML(); // workaround 權宜之計: iconSize 的處理還是有問題。 setTimeout('if(mapO)mapO.iconA[2].image=G_DEFAULT_ICON.image;',500); }; placeMapItem.step=function(i){ var _t=this; if(_t.run&&i<_t.stepA.length&&(!_t.loadMax||i<_t.loadMax)) mapO.add(mData[_t.stepA[i++]]),setTimeout('placeMapItem.step('+i+');',0/*i>40?400:i+i*i/4*/); else if(_t.done)_t.done(i); }; placeMapItem.loadMax=80; function placeMapItem(){ var _f=arguments.callee,i; if(_f.noPlace){ // 一開始不列出點 if(typeof _f.noPlace=='function')_f.noPlace(); return; } lostItem={}; _f.run=1; //showML(); showML.refresh=0; if(_f.step){ _f.stepA=[]; for(i in mData) lostItem[i]=mData[i],_f.stepA.push(i);//,mapO.add(mData[i]); setTimeout('placeMapItem.step(0);',0); }else{ for(i in mData)mapO.add(mData[i]); if(_f.done)_f.done(); } } // interface // 2008/9/6 15:7:34 //setSize.size=[880,320,240]; // width, height, menuWidth setSize.size='95%,70%,25%'.split(','); // width, height, menuWidth setSize.setContainer=function(){ try{ this.menuC=(this.menu=document.getElementById('markerList')).parentNode; // menuC: menu container return this.container=document.getElementById('map_canvas').parentNode; }catch(e){} }; function setSize(){ var _f=arguments.callee,s=_f.size,_s=s.join('\0').split('\0'),m,a=function(i,k){ if(!isNaN(s[i]))s[i]+='px'; if(typeof _s[i]=='string'&&(m=_s[i].match(/^(\d+)%$/))) k=k?'Height':'Width', _s[i]=Math.floor((window.innerHeight?window['inner'+k]:document.documentElement&&document.documentElement.clientHeight?document.documentElement['client'+k]:document.body['offset'+k])*m[1]/100); }; /* // from getWinStatus() with(document.body.style)width=height='100%'; sl('setSize: window.inner: '+window.innerWidth+','+window.innerHeight); sl('setSize: window.page: '+window.pageXOffset+','+window.pageYOffset); sl('setSize: screen: '+screen.width+','+screen.height); sl('setSize: document.documentElement.client: '+document.documentElement.clientWidth+','+document.documentElement.clientHeight); sl('setSize: document.body.scroll: '+document.body.scrollWidth+','+document.body.scrollHeight); sl('setSize: document.body.offset: '+document.body.offsetWidth+','+document.body.offsetHeight); sl('setSize: document.body.client: '+document.body.clientWidth+','+document.body.clientHeight); */ a(0); a(1,1); a(2); //sl('setSize: '+_s); a=_f.container; if(!a&&!(a=_f.setContainer()))return; with(a.style)width=s[0],height=s[1]; with(_f.menuC.style)width=s[2],height=s[1]; _f.menu.style.height=(_s[1]-_f.menu.offsetTop)+'px'; //sl('setSize: '+a.offsetWidth+'-'+_f.menuC.offsetWidth+'='+(a.offsetWidth-_f.menuC.offsetWidth)); //sl('setSize: '+_s[0]+'-'+_s[2]+'='+(_s[0]-_s[2])); initMap.flag.size=[ a.offsetWidth-_f.menuC.offsetWidth-(navigator.userAgent.indexOf('MSIE')==-1?13:1), // 13: 和 scrollbar 有關嗎?? (navigator.userAgent.indexOf('MSIE')==-1?_s[1]:_s[1]) // _s[1] 不能改成 a.offsetHeight ]; } showML.refresh=1; showML.closeMark='×'; showML.indexA='iA'; showML.selClass='sel'; showML.specialKind='sp'; showML.isSelR=new RegExp('(^|\\s+)'+showML.selClass); //showML.selO=null; showML.sel=function(o,removed){ var _t=this; if(typeof o!='undefined'){ // GMarker.setImage(src) if(!removed&&_t.selO&&_t.selO.setImage) try{_t.selO.setImage(mapO.icon().image);}catch(e){} // 用 try 是因為有時被刪了可是卻還是在(動作太快?),這時要 setImage 會出錯。 _t.selO=o; if(o&&o.setImage)o.setImage(mapO.icon(showSP.selectedI).image); } return _t.selO; }; showML.getName=function(o){ var name=o.parentNode.attributes.getNamedItem(this.indexA),type; if(name&&(name=name.nodeValue)&&(type=name.match(/^([a-z]+),(.+)$/i))){ //sl('showML.getName: ['+type[1]+'] '+type[2]+'('+getO.alias(type[2])+','+mapO.getO(type[1],getO.alias(type[2]))+')'); //name=,type=type[1]; return [getO.alias(type[2]),type[1]];//[name,type]; } }; showML.write=function(t){ try{document.getElementById('markerList').innerHTML=t;}catch(e){} }; function showML(o){ if(!mapO)return; // 尚未 initial? var _f=arguments.callee; if(o){ var name,type; if(type=_f.getName(o)){ name=type[0],type=type[1]; if(o.className=='closeMark') mapO.remove(name,type); else{ showML.sel(mapO.getO(type,name));//.setImage(mapO.icon(2).image); mapO.show(name,type); o=o.parentNode; for(var i=0,LI=library_namespace.get_tag_list('li', o.parentNode.parentNode);i'],a,i,j,id,OK={}; for(j in mapO.supportKind()){ a=mapO.getO(j); for(i in a){ //sl(a[i].name+','+a[i].address); if(a[i].name in lostItem)delete lostItem[a[i].name]; else if(('address' in a[i]) && (a[i].address in lostItem))delete lostItem[a[i].address]; id=typeof a[i].getLatLng=='function'?a[i].getLatLng():a[i].name; if(!(id in OK)) OK[id]=1, t.push('
  • ' +(a[i].name||i).replace(/<[^>]+>/g,'') +' ['+_f.closeMark+']
  • ');// title="remove marker" } } for(i in lostItem)t.push('
  • '+i+'
  • '); t.push(''); //sl(UnicodeToHTML(t.join('')),1); _f.write(t.join('')); // see dealWithLink() @ link.js if(typeof dealWithLink=='function')setTimeout('dealWithLink(0,1);',0); return false; } // show spot showSP.defaultI=0; // default icon index showSP.selectedI=2; // selected icon index function showSP(o,i){ if(o){ var name,type; if(type=showML.getName(o)){ name=type[0],type=type[1]; o=mapO.getO(type,name); if(o&&o.setImage&&o!=showML.sel()) //sl('showSP: set icon of ['+o.name+'] to '+i), o.setImage(mapO.icon(i).image); } return false; } } // 應用 function removeAll(){ showML.refresh=0,lostItem={}; if(mapO)mapO.removeAll(); // 尚未 initial? if(showML)showML.sel(null,1),showML.refresh=1,showML(); } // 不能造成 type 改變! function normalize_address(t) { var _f = arguments.callee, a = '0123456789'; if (!_f.dc) { _f.nr = new RegExp('[' + a + ']', 'g'); _f.dc = {}; for ( var i = 0; i < a.length; i++) _f.dc[a.charAt(i)] = i; } return t.replace(/[\s ]+/g, '').replace(_f.nr, function($0) { return _f.dc[$0]; }) //.replace(/號([^樓]+樓|之.{1,2})$/,'號'); ; }; /* http://www.post.gov.tw/post/internet/f_searchzone/sz_a_b_ta.jsp#a 縣市 鄉鎮市區 【市】為縣轄市 村里 直轄市:台北市、高雄市及省轄市:基隆市、新竹市、台中市、嘉義市、台南市以外地區由於路名結構變化較大,有些地區沒有路、街,僅有「村」、「里」名稱 鄰 路街 路名中不可使用(全、半形)阿拉伯數字,必須一律使用中文數字,如中正二路等,惟門牌號不必輸入。 新村、山莊、新城、工業區等與街、路同級之名稱 段 巷 文字巷 弄 號 \d(之\d)樓(之\d) 縣市鄉鎮區村里鄰路街段巷弄號樓 TODO: 806台灣高雄市前鎮區光華二路413號 */ _// JSDT:_module_ . /** * 解析地址 * @param {String} address 地址 * @returns * @_memberOf _module_ */ parse_address = function (address) { var a = {}, i, v, w = '縣市鄉鎮區村里鄰路街段巷弄號樓', r = new RegExp('[^' + w + ']+([' + w + '])', 'g'); var _ = address.replace(/[ \s]+/g, '').replace(/號([^樓F]{1,6})F$/, '號$1樓') .replace(/^(\d{3,5})?[台臺]灣/, '$1').replace(/^\d+/, function($0) { r.zip = $0; return ''; }).replace(r, function($0, $1) { v = $0; if (/縣市/.test(i = $1) && !r.zip) v.replace(/^\d{3}\d{2}?}/, function($0) { r.zip = $0; return ''; }); a[i] = v; //sl(v); return ''; }); // sl('['+address+'] --- ['+_+']'); return _ ? 0 : address; }; // 地址轉 index getO.n={}; // name(address) to mapO.getO's name getO.add=function(alias,name,type){ if(alias&&name&&alias!=name){ if(type&&mapO.getO(type,alias)&&!mapO.getO(type,name)){ var t=name;name=alias,alias=t; } //sl('getO.add: ['+alias+'] set to ['+name+']'), this.n[alias]=name; } }; getO.alias=function(name){return this.n[name]||name;}; function getO(name){ return mapO.getO(arguments.callee.n[name]||name); } /* search address sA(index of mData) sA({type(where):'',name:'',description:''}) sA(type(where),name,description) */ function sA(i,a,b){ if(!mData)return; // 尚未 initial? if(!(i in mData)||arguments.length>1) //sl('sA: search '+i), mapO.searchPoint.apply(mapO,arguments); else //sl('sA: call mData['+i+']('+mData[i].type+')'), mapO.searchPoint(mData[i]); return false; } // 先找尋現有資料 function sA2(adr,noFit){ var _f=arguments.callee; if(!noFit){ showFit(adr ,function(k,o){return k&&(o.name+o.description).indexOf(k)!=-1;} ,function(k){_f(adr,1);} ); return; } if(typeof adr_to_mData!='object'||mapO.LatLngR.test(adr))return sA(adr); //return sA(adr_to_mData[adr]||adr); if(!_f.c)_f.c=document.getElementById('guess'); if(!(adr in adr_to_mData)&&(adr.toLowerCase() in adr_to_mData)) //sl('sA2: ['+adr+']→['+adr.toLowerCase()+']'), adr=adr.toLowerCase(); if(adr_to_mData[adr] in mData){ var a=adr_to_mData[adr]; mData[a].show=1; // 置中 sA(a); if(showML.selO)mapO.showWindow(showML.selO); }else if(!_f.c)sA(adr); else mapO.getLocations(adr,function(r){ var cM='
    [×]
    '; if(gLocal){gLocal.searcher.setCenterPoint(showNeighbor.pointer.getLatLng()||mapO.setCenter()||'台灣');gLocal.s(adr);} if(!r.length){_f.c.innerHTML=cM+'使用 GClientGeocoder.getLocations 沒找到 ['+adr+']:
    '+mapO.GeoStatus(mapO.getLocations.errno),_f.c.style.display='block';return;} if(r.length==1&&adr==r[0][2]){sA(adr);if(showML.selO)mapO.showWindow(showML.selO);return;} var i=0,t=[cM+'對於 ['+adr+'],您是不是指:
      ']; for(;i '+r[i][2]+''); t.push('
    '); _f.c.innerHTML=t.join(''); _f.c.style.display='block'; });//sA(adr); return false; } /* 從 mData show 符合條件的 */ showFit.showZoom=40; // 這以下就 zoom showFit.limit=80; // 最多取點數 function showFit(k,func,notFound){ if(typeof k=='undefined'||!func)return; removeAll(); showML.write('頁面資料讀取中,請稍候…'); var i,p=[],b,_f=arguments.callee; for(i in mData) if(func(k,b=mData[i],i) && (b=mapO.searchPoint.call(mapO,b))) // 確定有找到才 c++ if(p.push(b), _f.limit&&p.length>_f.limit)break; if(p.length<_f.showZoom) if(p.length){ // zoom b=new GLatLngBounds(); for(i=0;i搜尋附近'; for(i=0;i'+p[i]+''; s+=' km'; if(overlay==m)m.openInfoWindowHtml('經緯度: '+m.getLatLng()+s); else if(!overlay&&point) p=m.getLatLng(),m.setLatLng(point), m.openInfoWindowHtml(point+'
    from: '+p+',
    distance: '+(p.distanceFrom(point)/1000).toFixed(3)+'km'+s); }); return this.pointer=m; }; showNeighbor.arg={ // 傳給 .getNeighbor() 的參數 //f:'n[i]=n[i][1][2];', // 不能改變結構!因為需要 getBoundsZoomLevel d:30, c:9 }; showNeighbor.forEach=function(a){ //sl('showNeighbor.forEach: ['+(typeof a[1][2])+'] '+a[1][2]); sA(a[1][2]); }; showNeighbor.byD=function(d){ var _t=this; if(d)_t.arg.d=d; if(_t.pointer)_t(_t.pointer.getLatLng()); return false; }; showNeighbor.notFound=function(address,address_not_found){ showML.write('抱歉,找不到 '+address+''+(address_not_found?'':' 附近的點')+'。'); }; function showNeighbor(l,f){//(location | [location, address], addSelf) if(!l)return; showML.write('頁面資料讀取中,請稍候…'); var _f=arguments.callee,i,o,adr; if(Array.isArray(l))adr=l[1],l=l[0]; //sl('showNeighbor: ['+l+','+adr+'] '+(l instanceof GLatLng)+', '+mapO.getLatLng(l+'')); if(!(l instanceof GLatLng)) // 無此資料。嘗試取得 loc.. return mapO.getLatLng(l+'',[function(p){_f([p,adr||l]);},function(p){if(p)return _f([p,adr||l]);_f.notFound&&_f.notFound(adr||l,1);}]); o=mapO.getNeighbor(l,_f.arg); if(o.length){ removeAll(); var bounds=new GLatLngBounds(); bounds.extend(l); for(i=0;i'+adr+' ':l)+' 四周 '+_f.arg.d+' km
    找到 '+o.length+'/(最多 '+_f.arg.c+') 個點。'); //sl('showNeighbor: search around '+l+' (四周 '+_f.arg.d+' km) get '+o.length+'/(max '+_f.arg.c+') results.'); } // =================================================== /* ** use Yahoo! Map to get position of a address _=this TODO: HISTORY: 2008/7/31 19:56:29 create http://tw.developer.yahoo.com/maps/ http://developer.yahoo.com/maps/ajax/V3.8/index.html */ var getLatLon= (function(){ var // class private ----------------------------------- // class name n='getLatLon', // running now r=0, // interval/timeout seed s=''+Math.random()*1e12, // { address: [function(lat, lng, address), not found function(address)], .. } o={}, // queue: [ adr, .. ] q=[], // map object m, // initial i=function(){ if(typeof YMap!='function'){ //sl(n+': Please include YMap first!'); return 1; } var o=document.createElement('div'); document.body.appendChild(o); o.style.width=o.style.height='1px'; // =0 會造成 .getArea() 出問題 YEvent.Capture(m=new YMap(o),EventsList.onEndGeoCode,c); o.style.visibility='hidden'; //o.style.display='none'; // 會造成 .getArea() 出問題 //s=Math.random()*1e12+''; }, // do query d=function(){ //sl(n+'.do query: '+q[0]); if(!q||!q.length)r=0; else m.geoCodeAddress(q.shift()); }, // catch function c=function(r){ var a=r.Address,f; if(f=_.interval) setTimeout(n+'("'+s+'");',f); else d(); if(a in o) if(f=o[a],r.success)f[0](r.GeoPoint.Lat,r.GeoPoint.Lon,a); else f[1]&&f[1](a); delete o[a]; }, // instance constructor --------------------------- _=function(a,f,nf){ // address, function, not found function if(a===s)return d(); if(!a||!f || !m&&i())return 1; o[a+='']=[f,nf]; //sl(n+': ('+q.length+')'+[a,f,nf]); q.push(a); if(!r)r=1,d(); }; // class public interface --------------------------- // interval (ms) _.interval=0; // class constructor --------------------------- i(); return _; })(); // (function(){ // =================================================== /* old // use Yahoo! Map // interval //getLatLon.t=200; // { address: [function, not found function], .. } getLatLon.o={}; // queue: [ adr, .. ] getLatLon.q=[]; // initial getLatLon.i=function(){ if(typeof YMap!='function'){ //sl('getLatLon: Please include YMap first!'); return 1; } var c=document.createElement('div'); document.body.appendChild(c); c.style.width=c.style.height=0; YEvent.Capture(this.m=new YMap(c),EventsList.onEndGeoCode,this.c); c.style.display='none'; this.T=Math.random()*1e12+''; }; // catch function getLatLon.c=function(r){ var t=getLatLon; if(t.t)setTimeout('getLatLon.d("'+t.T+'");',t.t);else getLatLon.d(); var f=t.o; if(r.Address in f) if(f=f[r.Address],r.success)f[0](r.GeoPoint.Lat,r.GeoPoint.Lon,r.Address); else f[1]&&f[1](r.Address); delete t.o[r.Address]; } // do query getLatLon.d=function(){ var _f=arguments.callee,_t=this,a,f,n; //sl('getLatLon.d: '+_t.q[0]); if(!_t.q||!_t.q.length)_t.r=0; else _t.m.geoCodeAddress(_t.q.shift()); }; // running //getLatLon.r=0; function getLatLon(adr,f,nf){ var _f=arguments.callee; if(adr===_f.T)return _f.d(); if(!adr||!f || !_f.m&&_f.i())return; if(!_f.q)_f.q=[]; //sl('getLatLon: ('+_f.q.length+')'+[adr,f,nf]); _f.o[adr]=[f,nf]; _f.q.push(adr); if(!_f.r){_f.r=1;_f.d();} } */ // =================================================== /* main map function _=this TODO: */ //var gMap= (function(){ // class private ----------------------------------- var // class interface ----------------------------------- _=function(){ // Dynamic Loading http://code.google.com/apis/ajax/documentation/#Dynamic //if(typeof GMap=='undefined')google.load("maps","2",{language:"ja_JP",callback:mapsLoaded}); // init member var _t=this,i; // initial instance object _t.locArray=[],_t.locArray2=[],_t.locArray_u={},_t.locArray2_u={},_t.iconA=[],_t.iconO={},_t.dMarkerO={}; _t.kinds={marker:GMarker,polyline:GPolyline,polygon:GPolygon,xml:GGeoXml}; // If this failed, maybe GMap didn't loaded? for(i in _t.kinds) if(i in _t)throw 'Error: ['+i+'] is already a member of me!'; else _t[i]={}; // 調整 GLatLng 的顯示 GLatLng.prototype.toS=function(p){ if(!p)p=_t.precision||0; return Number(this.lat()).toFixed(p)+','+Number(this.lng()).toFixed(p); }; GLatLng.prototype.toString=function(p){return '('+this.toS(p)+')';}; /* http://blog.wctang.info/2007/07/use-google-map-api-without-api-key.html Geocode 查詢每天有 50000 次的限制 使用 Geocoder 就是要連到 Google 去做查詢,而現在 Google 在做 Geocode 查詢時會在 Server 端做 API key 的檢查,這個就躲不掉了 http://blog.wctang.info/2007/07/use-google-map-geocoder-without-api-key.html */ if(GBrowserIsCompatible()&&!_t.geocoder) with(_t.geocoder=new GClientGeocoder()) setCache(null), // disable cache, 因為找到的都被管控了。 setBaseCountryCode('tw'); // 語系 //_t.readLoc(); _t.initMap.apply(_t,arguments);//return _t.initMap.apply(_t,arguments); }; // class public ----------------------------------- // prototype ----------------------------------- _.prototype={ // 這些函數可重寫 notFound:function(address,data){ return 1;//throw 'Address ['+address+'] not found!'; }, // 增加 overlay 後 runAfterAdd:function(obj,type,data,name){}, // 移除 overlay 後 runAfterRemove:function(obj,type){}, // 按 overlay 時 runOnClick:function(obj,type){}, precision:6, // 精度,算到小數點下第幾位。GMap 2008:6 defaultZoom:14, // 預設縮放 /* map, // GMap obj TODO: use GMarkerManager, http://code.google.com/apis/maps/documentation/overlays.html#Marker_Manager //handle array: marker={'lat,lng':GMarker}, // GMarker 地圖標記 polyline={points:GPolyline}, // GPolyline 折線 polygon={points:GPolygon}, // GPolygon 多邊形 xml={URL:GGeoXml}, // GGeoXml: xml/kml */ kinds:{}, supportKind:function(k){ return k?k in this.kinds:this.kinds; }, getKind:function(o){ for(var i in this.kinds) if(o instanceof this.kinds[i])return i; }, // 讀入先前 catch 的經緯度,存loc而不必每次search readLoc:function(){ var _t=this,t,i=0,l,a; if(!_t.locFP)_t.locFP='map_loc.dat'; // 紀錄 LatLng/地址 可供 searchPoint() 使用 // GDownloadUrl(url,callback) try{t=getU(_t.locFP);}catch(e){} _t.adr_to_loc={}; if(!t||!(t=t.replace(/\r/g,'').split('\n')).length)return; sl('Get '+t.length+' catched address records from ['+_t.locFP+'].'); for(;i1 && (l=a[0].split(',')).length==2) _t.adr_to_loc[a[1]]=new GLatLng(l[0],l[1]) //,sl('readLoc: ['+a[1]+'] '+_t.adr_to_loc[a[1]]) ; else sl('readLoc: error data: '+t[i]); }, // ** important ** 這邊不能作 object 之 initialization,否則因為 object 只會 copy reference,因此 new 時東西會一樣。initialization 得在 _() 中作! // locArray[]=[lat,lng,adr] sort by lat 給 writeLoc() & getNeighbor() 用,僅包含需要 search 的。 locArray:[], // 寫入 catched 的經緯度 writeLoc:function(s){ var _t=this,i,t=[],l,a=_t.precision,b,c; //sl('writeLoc: We will write data to ['+_t.locFP+'].'); if(!_t.locFP)return; for(i in _t.adr_to_loc) if(l=_t.adr_to_loc[i])try{ if(isNaN(b=Number(l.lat()))||isNaN(c=Number(l.lng())))throw new Error(1,'經緯度非數字'); t.push([b.toFixed(a),c.toFixed(a),i]); }catch(e){sl('writeLoc: Error: '+e.message+': ['+l+'] '+i+', ('+l.lat()+','+l.lng()+')');} sl('writeLoc: '+_t.locArray.length+'→'+t.length); // 不相同時才作處理 if(t.length!=_t.locArray.length){ t.sort(function(l,r){return l[0]-r[0]||l[1]-r[1];}); for(a=_t.locArray=[],b=_t.locArray_u={},c=[],i=0;iWarning: function.js is not included?'); } if(s)sl(''); return t; }, // locArray2[]=[lat,lng,adr] sort by lat 給 getNeighbor() 用,包括所有不需要 search 的地址。 locArray2:[], locArray_u:{},locArray2_u:{}, // 預防重複: locArray_u['lat,lng']=obj of locArray or locArray2 /* 取得鄰近的地點: 經緯度, 最大距離(km) http://blog.ben.idv.tw/2007/06/blog-post.html http://hk.geocities.com/hk_weather/big5/others/calculators.html http://blog.xuite.net/joy715/blog/9285691 http://iask.sina.com.cn/b/6263160.html mapO.getNeighbor([22.620096,120.333381],"sl(n[i][1][2]);"); return: f.d: 距離(km) f.c: 最多取用點數,<=0:全取,未設:default f.s: 最後時選取與否的篩選設置之函數 傳回數值越大越後面 f.D: 計算距離之函數,將用來比較 default [ [較準確的距離, [lat,lng,adr]],.. ] 求得較大概的距離(以距離平方比計算,比較快) [ [距離, [lat,lng,adr]],.. ] f.D=function(p,l){var a=l.lat()-p[0],b=l.lng()-p[1];return a*a+b*b;} f.f: 對選出之 spot 作最後處置之函數 default [ [較準確的距離, [lat,lng,adr]],.. ] 傳回地址 [ adr1, adr2,.. ] f.f= 'n[i]=n[i][1][2];' 傳回 obj [ [lat,lng,adr],.. ] f.f= 'n[i]=n[i][1];' 求得較準確的距離 [ [距離, [lat,lng,adr]],.. ] f.f= 'n[i][1]=l.distanceFrom(n[i][1]);' */ getNeighbor:function(l,f){ var _t=this,lat,lng,i,n=[],p=function(A){ // 計算最接近上限mLat之loc // c: 誤差 var i=0,j=A.length,a,b,c=f._d,mLat=lat-c; if(!j)return; //sl(mLat+'~'+(lat+c)); do{ //sl(Math.floor((i+j)/2)+'/'+A.length+','+A[a=Math.floor((i+j)/2)]); b=A[a=Math.floor((i+j)/2)][0]; if(b>mLat)j=a;else if(bc); //sl('start: from ['+a+'/'+A.length+'] '+A[a].join(':')+' to '+(lat+c));var tt=[]; for(i=a,mLat=lat+c,a=lng-c,b=lng+c;i')); }; if(typeof l=='string')l=l.split(','); //if(typeof l=='function'&&l.lat&&l.lng)lat=typeof l.lat=='function'?l.lat():l.lat,lng=typeof l.lng=='function'?l.lng():l.lng; if(l instanceof GLatLng)lat=l.lat(),lng=l.lng(); else lat=l[0],lng=l[1],l=new GLatLng(lat,lng); // 這邊起 l 為原始點之 GLatLng if(typeof f!='object') f=isNaN(f)?{f:f}:{d:f}; f._d=(f.d>0?f.d:20)/111; // 1度的實際長度~111公里。 if(!f.D)f.D=function(p,l){ //var a=lat-p[0],b=lng-p[1];return a*a+b*b; // 大概的,比較快。 return l.distanceFrom(new GLatLng(p[0],p[1])); // real distance }; //sl(lng+', '+lat+'; '+f._d); _t.writeLoc(); p(_t.locArray); _t.locArray2.sort(function(l,r){return l[0]-r[0]||l[1]-r[1];}); //sl('['+_t.locArray2.length+']
    * '+_t.locArray2.join('
    * ')); p(_t.locArray2); //sl('Get '+n.length+' records near ('+lat+','+lng+').'); // 由近至遠 sort if(typeof f.s=='undefined')f.s=function(l,r){return l[0]-r[0];}; // l, r: [distance by f.D,[lat,lng,adr]] if(f.s)n.sort(f.s); //for(i=0;if.c) n=n.slice(0,f.c>0?f.c:9); // 預設取 9 個 if(typeof f.f=='string')f.f=new Function('n','i','l',f.f); //sl('Run: [~'+n.length+'] by '+f.f); if(typeof f.f=='function') for(i=0;i]*>/ig,'\n').match(/[^\r\n]+[市區街路][^\r\n]+/)) //sl('('+m[1]+','+m[3]+') ['+a[0]+']'), if(!((m[1]+','+m[3]) in _t.locArray2_u))_t.locArray2.push(_t.locArray2_u[m[1]+','+m[3]]=[m[1],m[3],a[0]]); m=new GLatLng(m[1],m[3]); return func?func(m):m; // 搜尋已知地址 }else if((m=_t.adr_to_loc) && (m=m[adr]))//sl('getLatLng: handle adr_to_loc['+adr+']='+m[adr]+' get '+(func?c(m):m)/*+' by '+func*/), return func?c(m):m; // 搜尋未知地址 else if(func) //sl('Not catched: '+adr+''), return _t.geocoder.getLatLng(adr,typeof f=='function'?function(m){f(m,adr);}:c); // 原來需要用 arguments.callee.f,但若已經用 var 定義則可直接使用。 }, /* d={ name:'', // 這邊 name 被當作 id, title description:'HTML', type:'', data:['',''] //選用 optional: htm:'HTML' / function(obj){return 'HTML';}, //尚未用到︰ link:'', }; */ add:function(d,force){ if(!d||typeof d!='object')return this; var _t=this,o=_t.supportKind(d.type); if(!o){_t.searchPoint(d);return this;} //if(!(d.type in _t))_t[d.type]={}; var _S=_t[d.type],_m=this.map,a; //if(typeof _S!='object')sl('add: typeof ['+d.type+'] = '+(typeof _S)); if((d.name in _S)&&!force)return this; // 已存在 o=_t.kinds[d.type]; if(d.type=='marker'){ o=new o(new GLatLng(d.data[0],d.data[1]),_t.getMarkerO(d)); //if(d.zIndexP)o._zIndexProcess=o._zIndexProcess,o.zIndexProcess=d.zIndexP; // ** 可以利用 zIndexP 來在 infowindow is opened 時設定 z-index.. 沒用 @ 2008/6/30 19:43:43 }else a={points:d.data[0],levels:d.data[1],numLevels:4,zoomFactor:16}, o=new o.fromEncoded(d.type=='polyline'?a:{polylines:[a],fill:true,outline:true});//geodesic:true Geodesic means 'along great circle' _t._add(o,d); return this; }, searchPoint:function(adr,name,description){ var _f=arguments.callee,_t=this,type='marker',_M=_t[type],_m=_t.map,latlng,d; if(typeof adr=='object')d=adr,adr=adr.type;else d={type:adr,show:_f.show}; // 預設 searchPoint.show if(!d.name)d.name=name||adr; if(typeof d.description=='undefined') if(description)d.description=description; else if(d.name!=adr)d.description=adr; if(!d.type)return; if(isNaN(d.retry)&&!_t.geocoder.getCache())d.retry=2; // 找不到時重試次數 try{ if(adr in _M) //sl('We already have ['+adr+']'), _t.show(_M[adr],type); else _t.getLatLng(adr+='',function(point){ if(!point){ if(d.retry){ //sl('try once more('+d.retry+'): ['+adr+']'); d.retry--,_f.call(_t,d);return false; }else{ //sl('searchPoint: not found function: '+_t.notFound); return _t.notFound(adr,d); } }else{ if(adr in _M)return; // 可能經過太久才被 load? // ** 注意:這邊沒設 _M[adr]=_M[point.toUrlValue(_t.precision)] var p=new GMarker(latlng=point,_t.getMarkerO(d)); if(!d.name)d.name=p+''; //sl('found '+point+' '+d.name+', icon: '+p.getIcon().iconSize); //point='loc: '+point; if(typeof d.description=='undefined')d.description=point; else if(d.description==adr)d.description+='
    '+point; //_M=_M[adr]; if(!('address' in p))p.address=adr;else throw 'GMarker.address was used: ['+p.address+']!'; //sl('Last add '+adr+'..'); _t._add(p,d,type); } },d); }catch(e){sl('searchPoint: Error: '+adr+', '+_M+': '+e.message);}//throw e; return latlng; }, // private: 註冊 o 成為內容 d={},並設定 click 等 event _add:function(o,d,type){ if(!o)return; if(!d)d=o; if(!type)type=d.type; var _t=this,_S=_t[type],_m=this.map; //if(d.name)_S[d.name]=o; // 或許已經設定過了,這邊就需要跳過。 if(((d.name||d)+'') in _S) sl('_add: Warning: Type '+type+' 已存在 ['+(d.name||d)+']'+(_S[d.name||d].getLatLng?' '+_S[d.name||d].getLatLng():'')+('address' in _S[d.name||d]?' '+_S[d.name||d].address:'')+'!' //+'
    _add: 將以 ['+(o.name||d.name||d)+']'+(o.getLatLng?' '+o.getLatLng():'')+(o.address?' '+o.address:'')+' 覆寫。' ); _S[d.name||d]=o; // 必設!! if(_m)_m.addOverlay(o);//_t._addOverlay(o);// //if(o.getIcon)sl('_add: show '+o.getIcon().iconSize+' '+o.getIcon().image); o.name=d.name,o.dscr=d.description; // GMarker 中這兩個本來就有被用,偵測也只會發現已使用。 // another way to add tooltip: GControlPosition if(!('sHtm' in o)){ if('htm' in d)o.sHtm=typeof d.htm=='function'?d.htm.call(d,o,type):d.htm; else o.sHtm=(d.name?''+d.name+''+(d.description?'
    ':''):'')+(d.description||''); }else throw '['+type+'].sHtm was used: ['+o.sHtm+']!'; if(!('sHtmF' in o)){ if('htmF' in d) o.sHtmF=typeof d.htmF=='function'?d.htmF.call(d,o,type):d.htmF; }else throw '['+type+'].sHtmF was used: ['+o.sHtm+']!'; // openInfoWindowTabs: http://www.geocodezip.com/mapXmlTabsPlus.asp GEvent.addListener(o,"click",function(e){ _t.showWindow(o); _t.runOnClick(o,type,e&&e.target||window.event&&window.event.srcElement); }); if(d.show)_t.show(o,type); _t.runAfterAdd(o,type,d,d.name||d); }, _addOverlay:function(o){ var _t=this,_m=_t.map; if(!_t._aa)_t._aa=[]; if(o){_t._aa.push(o);return;} var i; while(i=_t._aa.shift()) _m.addOverlay(i); }, // icon setup defaultIconIndex:0, iconA:[], iconO:{}, icon:function(index){ var _t=this; if(Array.isArray(index)){ // 設定 icon _t.iconA=[]; for(var a,i=0,p,u;i=_t.iconA.length)index=_t.defaultIconIndex; //sl('icon: return icon['+index+'] '+(_t.iconA[index]?_t.iconA[index].iconSize+' '+_t.iconA[index].image:'G_DEFAULT_ICON')); return _t.iconA[index]||G_DEFAULT_ICON; }, dMarkerO:{}, // default marker option getMarkerO:function(mo,setMO){ // setMO: set default, 1: add, 2:reset var _t=this,i,a={icon:1,title:1,zIndexProcess:1,draggable:1}; // class GMarkerOptions _t.dMarkerO.icon=_t.icon(); if(setMO){ if(setMO==2)_t.dMarkerO={}; setMO=_t.dMarkerO; }else{ // 複製一份 setMO={}; for(i in _t.dMarkerO) //sl('getMarkerO: from default ['+i+']=['+_t.dMarkerO[i]+']'), setMO[i]=_t.dMarkerO[i]; } if(library_namespace.is_Object(mo)) for(i in a) if(a[i]&&typeof mo[i]!='undefined') //sl('getMarkerO: set ['+i+']=['+mo[i]+']'), setMO[i]=mo[i]; //sl('getMarkerO: icon: '+setMO.icon.iconSize+' '+setMO.icon.image); return setMO; }, /* 增加自己控制的 marker,會自動顯現,但不會列入管控,得自己設定。 usage: mapO.addMarker(dLoc.tw,{draggable:true}); */ addMarker:function(loc,opt){ var _t=this,_m=_t.map,m; if(_m){ if(Array.isArray(loc))loc=new GLatLng(loc[0],loc[1]); m=new GMarker(loc,_t.getMarkerO(opt)); //sl('addMarker icon: '+_t.getMarkerO(opt).icon.iconSize+' '+_t.getMarkerO(opt).icon.image); //sl('addMarker iconSize: '+_t.getMarkerO(opt).iconSize); _m.addOverlay(m); } return m; }, // f={p:position, m:method(pan/panBy/set), z:zoom} setCenter:function(f){ var _m=this.map; if(f instanceof GLatLng||!library_namespace.is_Object(f))f={p:f}; //sl('setCenter: setZoom ['+(f.z||null)+'] @ '+f.p+' by method ['+(f.m||'setCenter')+'].'); if(!isNaN(f.z))_m.setZoom(f.z); if(f.p){ if(Array.isArray(f.p))f.p=new GLatLng(f.p[0],f.p[1]); if(f.m=='pan')_m.panTo(f.p); else if(f.m=='panBy')_m.panBy(f.p); else _m.setCenter(f.p); } return _m.getCenter(); }, // zoom above 19 You can set zoom up to 30 by using setCenter() not by setZoom() or zoomIn() firefox: 45.1238,-123.1138 http://esa.ilmari.googlepages.com/highres.htm /* eval('error_noImage=p(10121);',mapO.map); sl(error_noImage); */ zoom:function(z){ var _t=this,_m=_t.map,m; if(typeof z=='string'&&(m=z.match(/^[+-]/)))z=_m.getZoom()+(m[0]=='+'?z:-z); if(z)_m.setZoom(z);//try{_m.setCenter(_m.getCenter(),z);}catch(e){} // 中文中, enableContinuousZoom()? 這麼搞會出錯 return _m.getZoom(); }, // show, or focus. f={noCenter:false, redraw: false} show:function(name,type,f){ var _t=this,_S=_t[type],_m=_t.map,inC; // inC: in control if(typeof name=='string') if(name in _S)_S=_S[name],inC=1; else _S=0; else _S=name; if(typeof _S!='object'||!_S)return; if(_S.isHidden&&_S.isHidden())_S.show(); if(typeof f!='object')f={noCenter:f}; // default: don't set to center if(!f.noCenter){ var p=_t.getPoint(_S,type); //sl('show: center= '+p); if(_m){ _m.setCenter(p); if(_m.getZoom()<9)_m.setZoom(_t.defaultZoom); if(inC)_t.showWindow(_S,p); // 未管控就 showWindow 會有奇妙的結果。 } } if(f.redraw && _S.redraw)_S.redraw(true); // Front/back order of markers can be messed simply by moving them in south-north direction. (v1) http://koti.mbnet.fi/ojalesa/exam/anim_v2.html return _t; }, // show HTML window (obj, point) o.sHtmF=show HTML flag: {maxContent:'', ..}: see class GInfoWindowOptions showWindow:function(o,p){ //sl('showWindow: '+(p||o.openInfoWindowHtml)); if(typeof o.openInfoWindowHtml=='function') o.openInfoWindowHtml(o.sHtm,o.sHtmF); // enableMaximize() else this.map.openInfoWindowHtml(p||this.getPoint(o),o.sHtm,o.sHtmF); }, // get the GLatLng of the object getPoint:function(o,type){ if(!type)type=this.getKind(o); //sl('getPoint: ['+type+']'+o.name); if(type=='marker'&&typeof o.getLatLng=='function')return o.getLatLng(); if(typeof o.getBounds=='function') return o.getBounds().getCenter(); if(typeof o.getCenter=='function') return o.getCenter(); if(typeof o.getVertexCount=='function') return o.getVertex(Math.floor(o.getVertexCount()/2)); }, getZoom:function(o,type){ if(!type)type=this.getKind(o); //sl('getPoint: ['+type+']'+o.name); if(typeof o.getBounds=='function') return this.getBoundsZoomLevel(o.getBounds()); // 得到適當的 zoom //if(type=='marker')return _t.defaultZoom; return _t.defaultZoom; }, initMap:function(id,latlng,f){ // container, center, other initial setting flags var _t=this,_m,a; // 檢查當前瀏覽器是否支持地圖 API 庫 if(GBrowserIsCompatible()){ // 指定GMap使用的圖層 @ id if(typeof id=='string')id=document.getElementById(id); if(!id)return _t; _t.canvas=id; // container object if(!f)f={}; if(!f.size) f.size=f.x&&f.y?[f.x,f.y]:[640,320]; if(Array.isArray(f.size))f.size=new GSize(f.size[0],f.size[1]); _m=_t.map=new GMap2(id,f);//=new google.maps.Map2(); // 設定中心點座標 _m.setCenter(latlng||new GLatLng(0,0),7); // default center. //_m.setMapType(G_HYBRID_MAP); _m.addMapType(G_PHYSICAL_MAP); // 地形圖 _m.addMapType(G_SATELLITE_3D_MAP); // with the Google Earth Browser Plug-in // 控制元件 客制化: http://julian.norway.idv.tw/index.php/archives/322 //_m.addControl((new GHierarchicalMapTypeControl()).addRelationship(G_SATELLITE_MAP, G_HYBRID_MAP, "Labels", true)); //_m.removeMapType(G_HYBRID_MAP); _m.addControl(a=_t.overviewMap=new GOverviewMapControl(new GSize(_m.getSize().width/2.5,_m.getSize().height/2))); // 可折疊的縮小圖 a.hide(); // show(), hide(). //a.getOverviewMap().addControl(new GMenuMapTypeControl(1)); must use setTimeout: getOverviewMap() is not available until after the module has loaded. _m.addControl(new GLargeMapControl()); // 加入地圖縮放工具 _m.addControl(new GMenuMapTypeControl(1));//GMapTypeControl(1) // 切換地圖型態的按鈕 _m.addControl(new GScaleControl()); // 地圖比例尺 _m.enableScrollWheelZoom(); _m.enableContinuousZoom(); // 平滑放大 GEvent.addListener(_m,'mouseover',function(){_m.showControls();}); GEvent.addListener(_m,'mouseout',function(){_m.hideControls();}); }else{ sl('抱歉,您的瀏覽器不支援 Google Maps!'); } return _t; }, /* 移除所有管控項 c.f., this.map.clearOverlays() */ removeAll:function(type){ var _t=this,i,o; if(!type)for(i in _t.kinds) arguments.callee.call(this,i); else{ //sl('removeAll: ('+(typeof type)+') ['+type+'], '+(typeof _t[type])); //o=[];for(i in _t[type])o.push(i);for(i=0;iw&&w>0)x=w; if(y>h&&h>0)y=h; (new GControlPosition(G_ANCHOR_TOP_LEFT,new GSize(x,y))).apply(o); _t.showContextMenu(1); }); _t.showContextMenu(0); return o; }, showContextMenu:function(v){ var o=this.contextMenu; if(o)o.style.visibility=v||typeof v=='undefined'?'visible':'hidden'; }, // get overlay getO:function(type,name){ var s=this[type]; return name?name in s?s[name]:null:s; }, // get name of the type getOArray:function(type){ var i,a=[],o=this[type]; if(o)for(i in o)a.push(i); return a; }, /* var i,t=[],o; o=GGeoXml.prototype;//GMap2.prototype sl('['+(typeof o)+'] '+(o+'').replace(/\n/g,'
    ')+'
    ',1);for(i in o)t.push('['+(typeof o[i])+'] '+i);sl(t.sort().join('
    ')); TODO: GEvent.addListener(map,"addoverlay",function(overlay){if(overlay.name){}}); */ loadXML:function(URL){ var _t=this,x=new GGeoXml(URL); // .getDefaultCenter(), .getDefaultBounds() 可能是 null _t.setCenter({p:x.getDefaultCenter(),z:x.getDefaultBounds(),m:'pan'}); _t.map.addOverlay(x); return _t.xml[URL]=x; }, //resize map resize:function(x,y){ with(this.map.getContainer().style) width=x+'px',height=y+'px'; }, // 去除商標, Copyright message removeTM:function(l){ var a=this.canvas; if(!a)return; a=library_namespace.get_tag_list('a'),i=a.length,t=1; //sl('removeTM: '+UnicodeToHTML(document.getElementById('map_canvas').innerHTML)); for(;i>0&&(t||l);){ i--; // http://www.google.com/intl/en_ALL/help/terms_maps.html if(t && a[i].href.indexOf('terms_maps')!=-1 && a[i].parentNode.tagName.toLowerCase()=='div'){ //sl('removeTM: remove copyright: '+a[i].href); //sl('removeTM: remove copyright: '+UnicodeToHTML(a[i].parentNode.innerHTML)); removeNode(a[i].parentNode,1); // 連這div都刪除會有奇怪現象發生 t=0; }else if(l && a[i].innerHTML.indexOf('poweredby.png')!=0){ //sl('removeTM: remove logo: '+UnicodeToHTML(a[i].parentNode.innerHTML)); removeNode(a[i].parentNode,1); l=0; } } } }; // _.prototype= return _; })(); // (function(){ // =================================================== /* 2008/9-10/1 搜尋用代理工具 usage: google.load("search","1",{language:"ja_JP",callback:loadSearch}); function loadSearch(){ gSearch=new getSearch(function(r,p){ sl(''+r.title+'
    '+r.content+'
    '); }); } TODO: Yahoo! Search BOSS http://developer.yahoo.com/search/boss/ LocalSearch: http://www.google.com/uds/samples/apidocs/static-tiles.html http://code.google.com/apis/ajaxsearch/documentation/reference.html#_class_GlocalSearch */ function getSearch(fn,kind){ // handle function, kind: Web/Local if(!kind)kind='Web'; var _t=this,_s=typeof google!='undefined'?google.search:0; if(!_s||!_s[kind+'Search'])return; _s=_t.searcher=new _s[kind+'Search'](); if(kind=='Local'){ //sl('Set center: '+'Taiwan'); _s.setCenterPoint('台灣');//Taiwan _s.setResultSetSize(google.search.Search.LARGE_RESULTSET); //_s.setCenterPoint("93108"); }else{ _s.setNoHtmlGeneration(); //.addSearcher(_s,(new google.search.SearcherOptions()).setExpandMode(google.search.SearchControl.EXPAND_MODE_OPEN)); } _s.setResultSetSize(google.search.Search.LARGE_RESULTSET); _s.setSearchCompleteCallback(_t,_t.searchComplete[kind],[_s]); if(fn)_t.sf=fn; return _t; } getSearch.prototype={ // country translate countryT:{Taiwan:'台灣'}, searchComplete:{ Local:function(searcher){ var r=searcher.results,i=0,a,b,j; if(r&&r.length>0)for(;ipage '+p+':'); if(r&&r.length)for(;i