1. 程式人生 > >百度地圖車輛運動軌跡

百度地圖車輛運動軌跡

先看效果:

下面是程式碼:

頁面程式碼:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=7" />
<title>回放目標軌跡</title>
<style type="text/css">
*{font-size:12px;}
body,html{margin:0px;padding:0px;overflow:hidden;}
#tip{position:absolute;z-index:100000;width:auto;padding:5px;color:#039;font-weight:bold;background:#FFF;display:none;}
</style>
<script type="text/javascript" src="api-v=1.2"></script>
<script type="text/javascript" src="goome.maps.js"></script>
<script type="text/javascript" src="WdatePicker.js-v=1.0.1.1"></script>
<script type="text/javascript" src="cn.js-v=1.0.1.1"></script>
<script type="text/javascript" src="jquery-1.3.2.min.js.gzjs"></script>
<script type="text/javascript" src="underscore.js-v=1.0.1.1"></script>
<script type="text/javascript" src="popupmarker.js-v=1.0.1.1"></script>
<script type="text/javascript" src="core.js-v=1.0.1.1"></script>
<script type="text/javascript" src="playback.js-v=1.0.1.1"></script>
<script type="text/javascript">
function restFrame(){
	var w = document.documentElement.clientWidth;
	var h = document.documentElement.clientHeight;
	var topMenuHeight = 32;//頂部選單區域的整體高度
	var divCanvas = document.getElementById("map");
	divCanvas.style.height= (h- topMenuHeight)+"px";
	divCanvas.style.width= w+"px";
}
//,"http://his-dx.vehicling.net/"
var PlayBack = new PlayBack("map",65979,"GT02",65);
function init(){
	restFrame();
	PlayBack.createMap("cn");
}
document.onmousemove = mouseCoords;

//getMaxDate生成客戶端本地時間
function getMaxDate(){
	var t = new Date();
	var maxDate = [t.getFullYear(), t.getMonth()+1, t.getDate()].join('-');
	maxDate += ' ' + t.toLocaleTimeString();
	return maxDate; 
}
//getMinDate生成客戶端本地時間
function getMinDate(){
	var t = new Date();
	t.setMonth(t.getMonth() - 2);//最小時間少2個月
	var maxDate = [t.getFullYear(), t.getMonth()+1, t.getDate()].join('-');
	maxDate += ' ' + t.toLocaleTimeString();
	return maxDate; 
}
</script>
</head>
<body onResize="restFrame();" onLoad="init();">
<span id="tip">正在載入資料,請耐心等待.......</span>
<div style="font-size:12px;height:30px;text-align:center;background:#C5CFD6;border-bottom:1px solid #999;">
	武漢的士 從:
    <input type="text" name="from" value="2012-05-08 16:05:52" id="from" readonly onClick="WdatePicker({dateFmt:'yyyy-MM-dd HH:mm:ss',maxDate: getMaxDate

(),minDate:getMinDate()})" class="Wdate" />
	到:
    <input type="text" name="to" value="2012-05-08 17:05:52" id="to" readonly onClick="WdatePicker({dateFmt:'yyyy-MM-dd HH:mm:ss',maxDate: getMaxDate

(),minDate:getMinDate()})" class="Wdate" />
	頻    率:
    <select name="freq" id="freq" onchange="PlayBack.Frequency = this.value">
        <option value="10000">正常-10</option>
        <option value="5000">2倍正常-5</option>
        <option value="3000">快-3</option>
        <option value="1000">比較快-1</option>
        <option value="500" >很快-0.5</option>
        <option value="100">非常快-0.1</option>
        <option value="10" selected>快得不得了</option>
    </select>
	秒
    <input id="PLAY" onClick="PlayBack.getDataFrist(document.getElementById('from').value,document.getElementById('to').value,document.getElementById('freq').value)" 

type="button" value="開始回放" />
    <input id="STOP" onClick="PlayBack.stopPlay()" type="button" value="停止播放" style="display:none;"/>
    <input id="mdTime" type="hidden" value=""/>
</div>
<div id="map"></div>
</body>     
</html>


主要js:

playback.js-v=1.0.1.1

// JavaScript Document
var map = "";
var _isBMap_ = typeof BMap !== "undefined";
var PlayBack = function(mapId,user_id,productType,sudu, url){
	this.container = mapId;
	this.user_id = user_id;
	this.map = null;
	this.productType = productType;
	this.overSpeed = sudu<60?80:sudu;
	this.AJAX_URL = url || "";
	this.REQUESR_URL = "http://his.10086care.com/GetDataService?method=getHistoryMByMUtc";//呼叫別的網站的webservice以獲取座標
	this.MAP_CENTER_LAT = 22.573978188551297;
	this.MAP_CENTER_LNG = 113.92078757286072;
	this.DEFAULT_DAYS = 6*24*60*60;
	this.RECORDS_LENGTH = 1000;
	this.MARKERS_OBJ = {};
	this.STATIC_MARKER = [];
	this.mapType =(typeof BMap == 'undefined')?"GOOGLE":"BAIDU";//預設地圖型別
	this.DEFAULT_ZOOM = 5;
	this.DISTANCE = 0;
	this.POLY_LINE_MARKER = [];
	this.DATA_REQUEST = true;
	this.FROM_TIME = null;
	this.TO_TIME = null;
	this.NEXT_TIME = null;
	this.LAST_DATA = [];
	this.PRE_DATE_TIMR = null;
	this.LAST_DATA_ = [];
	this.PRE_DATE_TIMR_ = null;
	this.RUN_TIME = 0;
	this.STOP_TIME = 0;
	this.EXCURSION_COUNT = 0;
	this.FRIST_LOAD = true;
	this.TIMER = "-1";
	this.HISTORY_PLAY_FLAG = true;
	this.Frequency = null;
	this.BUTTONS_ID = ["PLAY","STOP"];
	this.PLAY_OVER = false ;
	this.CROSS_DATA_1 = null;
	this.CROSS_DATA_2 = null;
	this.GL = false;//最後一點是否被過濾掉
	this.needGetData = false; 
};
PlayBack.prototype.createMap = function(lang){
	this.lang = lang;
	this.map = new goome.maps.Map({id:"map",lang:lang,lat:this.MAP_CENTER_LAT,lng:this.MAP_CENTER_LNG,zoom:this.DEFAULT_ZOOM});
	goome.maps.event.addListener(this.map,"mousemove",PlayBack.mapMouseMove);
};
PlayBack.prototype.getDataFrist = function(from,to,q){//第一次取GPS資料
	this.buttonAttribute(this.BUTTONS_ID[0],true,true);
	if(from==""||to=="") return;//開始和結束日期都不能為空
	var FROM_TIME = new Date(from.replace(/-/g, "/"));
	var TO_TIME = new Date(to.replace(/-/g, "/"));
	PlayBack.RUN_TIME = 0; //每次播放重置停留時間
	
	var timeDiff = (TO_TIME - FROM_TIME) / 1000;
	if(timeDiff < 0){
		alert(lg.distime);
		this.buttonAttribute(this.BUTTONS_ID[0],false,true);
		return;
	}
	if(this.FRIST_LOAD){//第一次回放
		this.FROM_TIME = from;
		this.TO_TIME = to;
		this.NEXT_TIME = from;
	}else{//不是第一次
		PlayBack.HISTORY_PLAY_FLAG = true;
		if(getTimeDiff(to,this.TO_TIME)>10||!PlayBack.PLAY_OVER){//如果修改了結束時間大於之前的結束時間並且不是第一次播放,並且結束時間大於之前的結束時間
			PlayBack.DATA_REQUEST = true;
		}else{
			PlayBack.DATA_REQUEST = false;
		}
		if(this.FROM_TIME!=from){//開始時間發生了變化,則刪除上次播放的資訊,重新播放
			clearTimeout(this.TIMER);
			this.GL = false;
			this.clearOverLayer();
			this.POLY_LINE_MARKER = [];
			this.FRIST_LOAD = true;
			this.DISTANCE = 0;
			this.FROM_TIME = from;
			this.NEXT_TIME = from;
			this.TO_TIME = to;
		}else{
			if(getTimeDiff(to,this.TO_TIME)<=10&&PlayBack.PLAY_OVER){//播放結束
				alert(lg.playOverTip[0] + PlayBack.FROM_TIME +lg.playOverTip[1] + PlayBack.TO_TIME);
				this.buttonAttribute(this.BUTTONS_ID[0],false,true);
				return;
			}
		}
	}
	this.Frequency = q||100;
	if(!this.FRIST_LOAD&&!PlayBack.PLAY_OVER){//上次資料還沒播放完畢
		this.TO_TIME = to;
		PlayBack.buttonAttribute(PlayBack.BUTTONS_ID[0],false,false);
	}else{		
		this.TO_TIME = to;
		this.PLAY_OVER = false;
		this.ajaxRequest();
	}
};
PlayBack.prototype.getDataCallBack = function(msg){//第一次取完資料回撥
	document.getElementById('tip').style.display = "none";
	PlayBack.buttonAttribute(PlayBack.BUTTONS_ID[0],false,true);
	if(!msg){
		alert(lg.playOverTip[0] + PlayBack.FROM_TIME +lg.playOverTip[1] + PlayBack.TO_TIME);
		var text = PlayBack.getTxtByCount();
		if(PlayBack.MARKERS_OBJ.update) PlayBack.MARKERS_OBJ.update({text:text});
		PlayBack.buttonAttribute(PlayBack.BUTTONS_ID[0],false,true);
		PlayBack.PLAY_OVER = true ;
		return;
	}
	PlayBack.buttonAttribute(PlayBack.BUTTONS_ID[0],true,false);
	if(msg){
		PlayBack.GL = false;
		var poly = [];
		var pArray = [];//點陣列
		if(!PlayBack.FRIST_LOAD&&PlayBack.LAST_DATA.length>0){//如果不是第一次請求資料,則把上次線條的最後一個點也加上
			poly = [new goome.maps.LatLng(PlayBack.LAST_DATA[1], PlayBack.LAST_DATA[0])];
		}
		var tem = msg.split(";");
		if(PlayBack.FRIST_LOAD){
			PlayBack.LAST_DATA_ = tem[0].split(",");
			PlayBack.PRE_DATE_TIMR_ = PlayBack.LAST_DATA_[2];
		} 
		var dateLen = tem.length-1;
		for(var i=0;i<dateLen;i++){
			var flag = true;
			var rs = tem[i].split(",");			
			var _diffTime = getTimeDiff(utcToLocal(rs[2]),utcToLocal(PlayBack.LAST_DATA_[2]));//當前點和上一個正常點之間的差,經過過濾之後的點
			var _dis_time = getTimeDiff(utcToLocal(rs[2]),utcToLocal(PlayBack.PRE_DATE_TIMR_));//當前點和最近的上一個點之間的時間差
			PlayBack.LAST_DATA_ = rs;
			PlayBack.PRE_DATE_TIMR_ = rs[2];
			if((PlayBack.productType.indexOf("GT02")>-1||PlayBack.productType=="LY-H810")){//&&i<(tem.length-2)//PlayBack.productType=="GT02"||PlayBack.productType=="GT02+"||PlayBack.productType=="GT02A"gt02和gt02+ 和 gt02A過濾漂移點
				//英文版b/s和c/s版過濾時間間隔從30秒提高到300秒,中文版過濾間隔時間超過30S的資料
				if(_dis_time > (PlayBack.lang == "en" ? 300 : 30 )){
					PlayBack.EXCURSION_COUNT ++;
					rs = [PlayBack.LAST_DATA_[0],PlayBack.LAST_DATA_[1],rs[2],0];
					if(i==(dateLen-1))PlayBack.GL = true;//表示最後一個點被過濾掉了
					continue;
				}
				if(rs[3] < 5){//過濾速度小於5的資料。
					PlayBack.EXCURSION_COUNT ++;
					rs = [PlayBack.LAST_DATA_[0],PlayBack.LAST_DATA_[1],rs[2],0];
					if(i==(dateLen-1))PlayBack.GL = true;//表示最後一個點被過濾掉了
					continue;
				}
				if(rs[3] < 10 && PlayBack.EXCURSION_COUNT > 5&&rs[3] >= 5 ){
					PlayBack.EXCURSION_COUNT ++;
					rs = [PlayBack.LAST_DATA_[0],PlayBack.LAST_DATA_[1],rs[2],0];
					if(i==(dateLen-1))PlayBack.GL = true;//表示最後一個點被過濾掉了
					continue;
				}
				if(rs[3] >= 10 && rs[3] < 15 && PlayBack.EXCURSION_COUNT > 8 && PlayBack.LAST_DATA_[3] < 5){
					PlayBack.EXCURSION_COUNT ++;
					rs = [PlayBack.LAST_DATA_[0],PlayBack.LAST_DATA_[1],rs[2],0];
					if(i==(dateLen-1))PlayBack.GL = true;//表示最後一個點被過濾掉了
					continue;
				}
				PlayBack.EXCURSION_COUNT = 0;
				poly.push(new goome.maps.LatLng(rs[1], rs[0]));
				pArray.push(rs);
			}else{
				poly.push(new goome.maps.LatLng(rs[1], rs[0]));
				pArray.push(rs);
			}
		}
		if((tem.length-1) == PlayBack.RECORDS_LENGTH){
			PlayBack.NEXT_TIME = tem[tem.length-2].split(",")[2].split(".")[0];
			PlayBack.DATA_REQUEST = true;
			PlayBack.needGetData = true;
		}else{
			PlayBack.needGetData = false; //返回資料小於1000條將不需要再取資料
			PlayBack.DATA_REQUEST = false;
			//在軌跡播放完畢的情況下避免請求的最後一個點被過濾導致位置不準
			if(PlayBack.GL){//如果最後請求的資料點被過濾掉了
				poly.push(new goome.maps.LatLng(PlayBack.LAST_DATA_[1], PlayBack.LAST_DATA_[0]));
				pArray.push(PlayBack.LAST_DATA_);
			}
		}
		var flightPath = new goome.maps.Polyline({path:poly,strokeColor:"#00FF00",strokeOpacity:0.9,strokeWeight:5}); 
		flightPath.setMap(PlayBack.map);
		PlayBack.POLY_LINE_MARKER.push(flightPath);
		PlayBack.playMarker(pArray);
	}
};

PlayBack.prototype.playMarker = function(array){//實現Marker播放功能
	if(PlayBack.FRIST_LOAD){
		var txt = "";
		if(array.length==0){
			PlayBack.FRIST_LOAD = false;
			PlayBack.LAST_DATA = PlayBack.LAST_DATA_;
			PlayBack.PRE_DATE_TIMR = PlayBack.PRE_DATE_TIMR_;
			txt = PlayBack.getTxtByRecord(PlayBack.LAST_DATA);
			PlayBack.ajaxRequest();
		}else{
			PlayBack.LAST_DATA = array[0];
			PlayBack.PRE_DATE_TIMR = array[0][2];
			txt = PlayBack.getTxtByRecord(array[0]);
		}
		var point = new goome.maps.LatLng(PlayBack.LAST_DATA[1],PlayBack.LAST_DATA[0]);
		PlayBack.map.setCenter(point);
		PlayBack.map.setZoom(13);
		PlayBack.MARKERS_OBJ = new PopupMarker({position:point,map:PlayBack.map,icon:"green.gif",text:txt,showpop:true});
		PlayBack.POLY_LINE_MARKER.push(PlayBack.MARKERS_OBJ);
		if(array.length==0)return;
	}
	var i = 0;		
	var paly = function() {
		if(PlayBack.HISTORY_PLAY_FLAG) {
			if(i<array.length) {	
				if(array[i][3]>PlayBack.overSpeed){
					var color = "#FF00FF";
					if(array[i][3]>1.5*PlayBack.overSpeed)color = "#FF0000";
					var points = [new goome.maps.LatLng(array[i][1], array[i][0]),new goome.maps.LatLng(PlayBack.LAST_DATA[1], PlayBack.LAST_DATA[0])];
					var FP = new goome.maps.Polyline({path:points,strokeColor:color,strokeOpacity:0.9,strokeWeight:5});    
					FP.setMap(PlayBack.map);
					PlayBack.POLY_LINE_MARKER.push(FP);
				}
				PlayBack.play(array[i]);
				i++;			
				PlayBack.TIMER = setTimeout(paly,PlayBack.Frequency);
			}else{
				if(PlayBack.DATA_REQUEST && PlayBack.needGetData){
					PlayBack.ajaxRequest();
				}else{
					alert(lg.playOverTip[0] + PlayBack.FROM_TIME +lg.playOverTip[1] + PlayBack.TO_TIME);
					var text = PlayBack.getTxtByCount();
					PlayBack.MARKERS_OBJ.update({text:text});
					PlayBack.buttonAttribute(PlayBack.BUTTONS_ID[0],false,true);
					PlayBack.PLAY_OVER = true ;
					PlayBack.NEXT_TIME = PlayBack.TO_TIME.split(".")[0];
				}
			}
		} else {
			PlayBack.TIMER = setTimeout(paly,PlayBack.Frequency);
		}
	};
	if(PlayBack.FRIST_LOAD){
		PlayBack.FRIST_LOAD = false;
		setTimeout(paly,1000);
	}else{
		paly();
	}
};
PlayBack.prototype.ajaxRequest = function(){
	var mdTime = document.getElementById('mdTime').value;
	PlayBack.NEXT_TIME = (PlayBack.NEXT_TIME < mdTime ? mdTime : PlayBack.NEXT_TIME);
	var parms = "&userID="+PlayBack.user_id+"&mapType="+PlayBack.mapType+"&pwd=123456&from="+localToUtc(PlayBack.NEXT_TIME)+"&to="+localToUtc(PlayBack.TO_TIME)+"&t="+new Date().getTime();
	var loadDiv = document.getElementById('tip');
	loadDiv.style.display = "block";
	loadDiv.style.top = (document.documentElement.clientHeight -20)/2+"px";
	loadDiv.style.left = (document.documentElement.clientWidth -150)/2+"px";
	_.ajax.jsonp( PlayBack.AJAX_URL + PlayBack.REQUESR_URL + parms+"&callback=PlayBack.getDataCallBack");
};
PlayBack.prototype.getTxtByRecord = function(record){//生成彈出視窗的文字
	var html=[];
	html.push('<font>');
	html.push('<span style="font-weight:bold;">'+lg.speed+':</span>'+record[3]+lg.kPerH+'<br/>');
	html.push('<span style="font-weight:bold;">'+lg.movement+':</span>'+formatKm2M(PlayBack.DISTANCE)+'<br/>');
	html.push('<span style="font-weight:bold;">'+lg.sign+':</span>'+utcToLocal(record[2])+'<br/>');
	if(PlayBack.STOP_TIME>0){
		html.push('<span style="font-weight:bold;">'+lg.idle+':</span>'+exchangeTime(PlayBack.STOP_TIME)+'<br/>');
	}
	html.push('</font>');
	return html.join("");
};
PlayBack.prototype.getTxtByCount = function(){//生成彈出視窗的文字
	var total = getTimeDiff(PlayBack.TO_TIME,PlayBack.FROM_TIME);
	var html=[];
	html.push('<font>');
	html.push('<span style="font-weight:bold;">'+lg.totalTime+':</span>'+exchangeTime(total)+'<br/>');
	html.push('<span style="font-weight:bold;">'+lg.movement+':</span>'+formatKm2M(PlayBack.DISTANCE)+'<br/>');
	html.push('<span style="font-weight:bold;">'+lg.duration+':</span>'+(exchangeTime(PlayBack.RUN_TIME)||0)+'<br/>');
	html.push('<span style="font-weight:bold;">'+lg.idle+':</span>'+exchangeTime(total-PlayBack.RUN_TIME)+'<br/>');
	html.push('</font>');
	return html.join("");
};
PlayBack.prototype.filterExcursion = function(array){//過濾漂移資料
	PlayBack.EXCURSION_COUNT ++;
	array[3] = 0;
	var text = PlayBack.getTxtByRecord(array);
	PlayBack.MARKERS_OBJ.update({text:text});
};
PlayBack.prototype.play = function(array){
	array[2] = utcToLocal(array[2]);
	var _diffTime = getTimeDiff(array[2],utcToLocal(PlayBack.LAST_DATA[2]));//當前點和上一個正常點之間的差,經過過濾之後的點
	var _dis_time = getTimeDiff(array[2],utcToLocal(PlayBack.PRE_DATE_TIMR));//當前點和最近的上一個點之間的時間差
	PlayBack.PRE_DATE_TIMR = array[2];
	if(_diffTime>600){//大於600秒就畫出靜止點
		PlayBack.createStaticMarker(array[2],_diffTime);
	}
	var latlng = new goome.maps.LatLng(array[1],array[0]);
	PlayBack.DISTANCE = distance(PlayBack.LAST_DATA[1],PlayBack.LAST_DATA[0],array[1],array[0],PlayBack.DISTANCE);
	var text = PlayBack.getTxtByRecord(array);
	PlayBack.MARKERS_OBJ.update({position:latlng,text:text});
	var bound = PlayBack.map.getBounds();
	if(!bound.contains(latlng)){//如果監控車倆沒有在地圖範圍內就重設地圖中心
		if(_isBMap_){
			PlayBack.map.setCenter(latlng);
		}else{
			PlayBack.map.panTo(latlng);
		}
	}
	if(array[3]>0){
		if(_diffTime>180){//考慮在速度比較慢的情況下,會隔點傳.
			PlayBack.STOP_TIME +=_diffTime;
		}else{//執行時間
			PlayBack.RUN_TIME +=_diffTime;
		}
		PlayBack.LAST_DATA = array;
	}
};
PlayBack.prototype.createStaticMarker = function(stime,dis_time){
	var txt = lg.idle+":"+exchangeTime(dis_time)+"<br>"+lg.start+PlayBack.LAST_DATA[2]+"<br>"+lg.end+stime;
	var point = new goome.maps.LatLng(PlayBack.LAST_DATA[1],PlayBack.LAST_DATA[0]);
	var marker = new PopupMarker({position:point,map:PlayBack.map,icon:"gray.gif",text:txt,showpop:false});
	PlayBack.STATIC_MARKER.push(marker);
};
PlayBack.prototype.stopPlay = function(){
	PlayBack.buttonAttribute(PlayBack.BUTTONS_ID[1],true,false);
	PlayBack.HISTORY_PLAY_FLAG = false;
};
PlayBack.prototype.clearOverLayer = function(){//重新播放,清楚地圖上所有的線條和圖示
	for(var i=0;i<PlayBack.POLY_LINE_MARKER.length;i++){
		PlayBack.POLY_LINE_MARKER[i].setMap(null);
	}
	for(var j=0;j<PlayBack.STATIC_MARKER.length;j++){
		PlayBack.STATIC_MARKER[j].setMap(null);
	}
};
PlayBack.prototype.buttonAttribute = function(id,bool,show){
	for(var i=0;i<this.BUTTONS_ID.length;i++){
		if(this.BUTTONS_ID[i]==id){
			document.getElementById(this.BUTTONS_ID[i]).disabled = bool;
			if(show)
				document.getElementById(this.BUTTONS_ID[i]).style.display = "";
			else 
				document.getElementById(this.BUTTONS_ID[i]).style.display = "none";
		}else{
			if(!show) document.getElementById(this.BUTTONS_ID[i]).style.display = "";
			else document.getElementById(this.BUTTONS_ID[i]).style.display = "none";
			document.getElementById(this.BUTTONS_ID[i]).disabled = false;
		}
	}
};
PlayBack.prototype.mapMouseMove=function(event){
	var latlng=event.latLng;
	var markpoint=this.fromLatLngToDivPixel(latlng);
	for(var i=0;i<PlayBack.STATIC_MARKER.length;i++){
		var point=this.fromLatLngToDivPixel(PlayBack.STATIC_MARKER[i].latlng());
		if(point.x<(markpoint.x+7)&&point.x>(markpoint.x-7)&&point.y<(markpoint.y+15)&&point.y>(markpoint.y-5)){
			PlayBack.STATIC_MARKER[i].show();
			return;
		}else{
			PlayBack.STATIC_MARKER[i].hide();
		}
	}
};


api-v=1.2

document.write('<link rel="stylesheet" type="text/css" href="http://api.map.baidu.com/res/12/bmap.css"/>');   document.write('<script type="text/javascript" src="http://api.map.baidu.com/getscript?v=1.2&key=&services=&t=11111111"></script>');


goome.maps.js

(function(window){window.goome=window.goome||{};goome.maps=goome.maps||{};goome.maps.event={};var isBMap,mapperKey,tempMaps;if(typeof BMap!="undefined"){tempMaps=BMap;goome.maps.event={};isBMap=true;mapperKey="baidu"}else{if(typeof google!="undefined"&&google.maps){tempMaps=google.maps;isBMap=false;mapperKey="google"}}goome.maps.event.addListener=function(map,name,handler){var self=map._source||map;if(self.addEventListener){self.addEventListener(name,function(event){event.latLng=new goome.maps.LatLng(event.point);handler.call(map,event)})}else{google.maps.event.addListener(self,name,function(event){event.latLng=new goome.maps.LatLng(event.latLng);handler.call(map,event)})}};var objectMapping={Map:{google:"Map",baidu:"Map"},LatLng:{google:"LatLng",baidu:"Point"},Point:{google:"Point",baidu:"Pixel"},Size:{google:"Size",baidu:"Size"},LatLngBounds:{google:"LatLngBounds",baidu:"Bounds"},InfoWindow:{google:"InfoWindow",baidu:"InfoWindow"},OverlayView:{google:"OverlayView",baidu:"Overlay"},Circle:{google:"Circle",baidu:"Circle"},Polyline:{google:"Polyline",baidu:"Polyline"},Marker:{google:"Marker",baidu:"Marker"}};for(var key in objectMapping){goome.maps[key]=eval(key)}function OverlayView(){}OverlayView.prototype.setMap=function(map){if(this._source.setMap){this._source.setMap(map?(map._source||map):null)}else{if(map){map=map._source||map;if(map.addOverlay){map.addOverlay(this._source)}}else{map=this._source.getMap();if(map){map.removeOverlay(this._source)}}}};OverlayView.prototype.getMap=function(){var map=this._source.getMap();return map?new goome.maps.Map(map):null};for(var key in {Circle:"",Polyline:"",Marker:""}){goome.maps[key].prototype.setMap=goome.maps.OverlayView.prototype.setMap;goome.maps[key].prototype.getMap=goome.maps.OverlayView.prototype.getMap}function Map(options){if(this===window){throw Error("use constructor to create a map instance")}if(options&&options.setZoom){this._source=options;return}if(typeof options!="object"||!options.id){throw Error("Map:parameter type error or required property missed")}var defaults={lang:"cn",sandbox:false,lat:{google:36.87962060502676,baidu:36.62060502676},lng:{google:111.6015625,baidu:108.6015625},zoom:{google:14,baidu:13}};var sandbox=options.sandbox||defaults.sandbox,lang=options.lang||defaults.lang,node=(typeof options.id==="string")?document.getElementById(options.id):options.id;var map;if(isBMap){map=new BMap.Map(node,{zoomLevelMin:5,zoomLevelMax:17});map.centerAndZoom(options.center||new BMap.Point(defaults.lng.baidu,defaults.lat.baidu),options.zoom||defaults.zoom.baidu);map.enableScrollWheelZoom();map.enableKeyboard();map.addControl(new BMap.NavigationControl());map.addControl(new BMap.ScaleControl());map.addControl(new BMap.OverviewMapControl());map.addControl(new BMap.MapTypeControl({type:BMAP_MAPTYPE_CONTROL_HORIZONTAL,mapTypes:[BMAP_NORMAL_MAP,BMAP_SATELLITE_MAP,BMAP_HYBRID_MAP]}))}else{var opts={zoom:options.zoom||defaults.zoom.google,scaleControl:true,center:options.center||new google.maps.LatLng(defaults.lat.google,defaults.lng.google),mapTypeId:google.maps.MapTypeId.ROADMAP,mapTypeControlOptions:{mapTypeIds:[google.maps.MapTypeId.ROADMAP,google.maps.MapTypeId.SATELLITE]}};if(lang=="cn"){opts.mapTypeId=google.maps.MapTypeId.ROADMAP;map=new google.maps.Map(node,opts)}else{map=new google.maps.Map(node,opts)}if(typeof overlay==="undefined"){overlay=new google.maps.OverlayView();overlay.draw=function(){};overlay.setMap(map)}else{if(sandbox){var ol=new google.maps.OverlayView();ol.draw=function(){};ol.setMap(map);sandbox.overlay=ol}}}this._source=map}Map.prototype.getDiv=function(){return this._source.getDiv?this._source.getDiv():this._source.getContainer()};Map.prototype.setZoom=function(m){this._source.setZoom(m)};Map.prototype.getZoom=function(){return this._source.getZoom()};Map.prototype.panBy=function(x,y){this._source.panBy(x,y)};Map.prototype.getMapTypeId=function(){return this._source.getMapTypeId?this._source.getMapTypeId():this._source.getMapType()};Map.prototype.getBounds=function(){return new goome.maps.LatLngBounds(this._source.getBounds())};Map.prototype.getCenter=function(){return new goome.maps.LatLng(this._source.getCenter())};Map.prototype.setCenter=function(latlng){this._source.setCenter(latlng._source||latlng)};Map.prototype.panTo=function(latlng){this._source.panTo(latlng._source||latlng)};Map.prototype.fromLatLngToDivPixel=function(latlng){if(this._source.pointToOverlayPixel){return new goome.maps.Point(this._source.pointToOverlayPixel(latlng._source||latlng))}else{return new goome.maps.Point(overlay.getProjection().fromLatLngToDivPixel(latlng._source||latlng))}};function LatLng(lat,lng){if(arguments.length!==1){var k=objectMapping.LatLng[mapperKey];this._source=isBMap?(new tempMaps[k](lng,lat)):(new tempMaps[k](lat,lng))}else{this._source=lat}}LatLng.prototype.equals=function(latlng){return this._source.equals(latlng._source||latlng)};LatLng.prototype.lat=function(){return(typeof this._source.lat==="function")?this._source.lat():this._source.lat};LatLng.prototype.lng=function(){return(typeof this._source.lng==="function")?this._source.lng():this._source.lng};function Size(w,h){if(arguments.length===1){this._source=w}else{this._source=new tempMaps[objectMapping.Size[mapperKey]](w,h)}this.width=this._source.width;this.height=this._source.height}Size.prototype.equals=function(size){return this._source.equals(size._source||size)};function LatLngBounds(sw,ne){if(arguments.length===1){this._source=sw}else{this._source=new tempMaps[objectMapping.LatLngBounds[mapperKey]](sw._source,ne._source)}}LatLngBounds.prototype.contains=function(latlng){if(this._source.contains){return this._source.contains(latlng._source||latlng)}else{if(this._source.containsPoint){return this._source.containsPoint(latlng._source||latlng)}}};LatLngBounds.prototype.getCenter=function(){return new goome.maps.LatLng(this._source.getCenter())};LatLngBounds.prototype.getNorthEast=function(){return new goome.maps.LatLng(this._source.getNorthEast())};LatLngBounds.prototype.getSouthWest=function(){return new goome.maps.LatLng(this._source.getSouthWest())};function Point(x,y){if(arguments.length===2){this._source=new tempMaps[objectMapping.Point[mapperKey]](x,y)}else{this._source=x}this.x=this._source.x;this.y=this._source.y}Point.prototype.equals=function(point){if(point._source){return this._source.equals(point.source)}else{return this._source.equals(point)}};function Circle(opts){if(opts&&opts.getMap){this._source=opts;return}if(!opts.radius||!opts.center){throw Error("Circle:required options property missed!")}opts.center=opts.center._source||opts.center;var circle;if(isBMap){circle=new tempMaps[objectMapping.Circle[mapperKey]](opts.center,opts.radius,opts)}else{circle=new tempMaps[objectMapping.Circle[mapperKey]](opts)}if(opts.map){opts.map=opts.map._source||opts.map;if(opts.map.addOverlay){opts.map.addOverlay(circle)}}this._source=circle}Circle.prototype.getBounds=function(){return new goome.maps.LatLngBounds(this._source.getBounds())};Circle.prototype.getCenter=function(){return new goome.maps.LatLng(this._source.getCenter())};Circle.prototype.setCenter=function(latlng){this._source.setCenter(latlng._source||latlng)};Circle.prototype.getRadius=function(){return this._source.getRadius()};Circle.prototype.setRadius=function(radius){this._source.setRadius(radius)};Circle.prototype.setOptions=function(opts){var props={strokeColor:"StrokeColor",strokeOpacity:"StrokeOpacity",strokeWeight:"StrokeWeight",fillColor:"FillColor",fillOpacity:"FillOpacity"};if(this._source.setOptions){this._source.setOptions(opts)}else{for(var key in opts){if(props.hasOwnProperty(key)){this._source["set"+props[key]](opts[key])}}}};function Polyline(opts){if(opts&&opts.setMap){this._source=opts;return}if(!opts.path){opts.path=[]}var apiPath=[],polyline;for(var index in opts.path){var item=opts.path[index];apiPath.push(item._source||item)}opts.path=apiPath;if(isBMap){polyline=new tempMaps[objectMapping.Polyline[mapperKey]](opts.path,opts)}else{if(opts.map&&opts.map._source){opts.map=opts.map._source}polyline=new tempMaps[objectMapping.Polyline[mapperKey]](opts)}if(opts.map){var m=opts.map._source||opts.map;if(m.addOverlay){m.addOverlay(polyline)}}this._source=polyline}Polyline.prototype.setOptions=function(opts){var props={strokeColor:"StrokeColor",strokeOpacity:"StrokeOpacity",strokeWeight:"StrokeWeight",path:"path"};if(this._source.setOptions){this._source.setOptions(opts)}else{for(var key in opts){if(props.hasOwnProperty(key)){this._source["set"+props[key]](opts[key])}}}};Polyline.prototype.getPath=function(){if(this._source.setOptions){var arr=[],gRet=this._source.getPath(),len=gRet.getLength(),i=0;for(;i<len;i++){arr.push(new goome.maps.LatLng(gRet.getAt(i)))}return arr}var ret=[];var result=this._source.getPath();for(var index in result){ret.push(new goome.maps.LatLng(result[index]))}return ret};Polyline.prototype.setPath=function(latlngs){if(latlngs.length<1){return}if(latlngs[0]._source){var origin=[];for(var index in latlngs){origin.push(latlngs[index]._source)}this._source.setPath(origin)}else{this._source.setPath(latlngs)}};Polyline.prototype.addPath=function(latlng,map){var path=this._source.getPath();path.push(latlng&&latlng._source);if(isBMap){this._source.setPath(path);(map&&map._source||this._source.getMap()).addOverlay(this._source)}};Polyline.prototype.clear=function(){if(isBMap){var map=this._source.getMap();if(!map){return}this._source.setPath([]);map.addOverlay(this._source)}else{var path=this._source.getPath();while(path.length){path.removeAt(0)}}};function Marker(opts,size,anchor){if(typeof opts==="object"&&opts.getMap){this._source=opts;return}if(!opts.position){throw Error("Marker:required options property missed!")}var position=opts.position._source||opts.position,marker;if(isBMap){if(opts.icon){var param;if(anchor&&anchor.width&&anchor.height){param={anchor:new BMap.Size(anchor.width,anchor.height)}}if(size&&size.width&&size.height){opts.icon=new BMap.Icon(opts.icon,new BMap.Size(size.width,size.height),param)}else{throw Error("Marker:parameter size with props width and height missed")}}marker=new tempMaps[objectMapping.Marker[mapperKey]](position,opts);if(opts.map){var map=opts.map._source||opts.map;map.addOverlay(marker)}}else{opts.position=position;if(opts.map){opts.map=opts.map._source||opts.map}marker=new tempMaps[objectMapping.Marker[mapperKey]](opts)}this._source=marker}Marker.prototype.getPosition=function(){return new goome.maps.LatLng(this._source.getPosition())};Marker.prototype.setPosition=function(latlng){this._source.setPosition(latlng._source||latlng)};Marker.prototype.getPosition=function(){return new goome.maps.LatLng(this._source.getPosition())};Marker.prototype.setTitle=function(title){this._source.setTitle(title)};Marker.prototype.getTitle=function(){return this._source.getTitle()};Marker.prototype.setIcon=function(url,size){if(isBMap&&arguments.length!=2){throw Error("Marker:parameter size:{width,height} for baidu map is missed")}if(this._source.setOptions){this._source.setIcon(url)}else{if(size&&size.width&&size.height){this._source.setIcon(new BMap.Icon(url,new BMap.Size(size.width,size.height)))}else{throw Error("Marker:required parameter size:property -width and height}")}}};Marker.prototype.getIcon=function(){var icon=this._source.getIcon();return typeof icon==="string"?icon:icon.imageUrl};Marker.prototype.setDraggable=function(flag){if(this._source.setDraggable){this._source.setDraggable(flag)}else{if(this._source.enableDragging){flag?this._source.enableDragging():this._source.disableDragging()}}};Marker.prototype.setVisible=function(flag){if(this._source.setVisible){this._source.setVisible(flag)}else{if(this._source.show){flag?this._source.show():this._source.hide()}}};Marker.prototype.setZIndex=function(index){this._source.setZIndex(index)};Marker.prototype.setOptions=function(opts){if(this._source.setOptions){this._source.setOptions(opts)}else{throw Error("Marker:not supported method - setOptions,use setter method directly")}};function InfoWindow(opts){if(opts&&opts.setContent){this._source=opts;return}if(!opts.hasOwnProperty("content")){throw Error("InfoWindow:options required property missed!")}if(isBMap){this._source=new tempMaps[objectMapping.InfoWindow[mapperKey]](opts.content,opts)}else{this._source=new tempMaps[objectMapping.InfoWindow[mapperKey]](opts)}}InfoWindow.prototype.open=function(map,marker){marker=marker._source||marker;map=map._source||map;if(this._source.open){this._source.open(map,marker)}else{if(marker.openInfoWindow){marker.openInfoWindow(this._source)}}};InfoWindow.prototype.close=function(){if(this._source.close){this._source.close()}else{if(this._source.hide){this._source.hide()}}};InfoWindow.prototype.getContent=function(){this._source.getContent()};InfoWindow.prototype.getPosition=function(){return new goome.maps.LatLng(this._source.getPosition())};InfoWindow.prototype.setContent=function(node){this._source.setContent(node)};InfoWindow.prototype.setZIndex=function(index){this._source.setZIndex(index)};InfoWindow.prototype.setPosition=function(latlng){this._source.setPosition(latlng._source||latlng)};InfoWindow.prototype.setOptions=function(opts){if(this._source.setOptions){this._source.setOptions(opts)}else{throw Error("InfoWindow:not supported method - setOptions,use setter method directly")}}})(window);


cn.js-v=1.0.1.1

var lg={
downMsg:'<br/><br/><h1>幫助</h1>        您可以通過“下載軌跡資料”功能,下載指定裝置某一日期內的移動痕跡。<br/><br/>步驟:<br/>1.選擇需要下載的指定裝置。<br/> 2.輸入需要下載的具體日期。<br/> 3.單擊“下載KML軌跡檔案”按鈕。<br/><br/><span style="color:red;">注意:如果單擊“下載”按鈕, 出現“沒有找到有效的軌跡資料!”提示資訊,表示當前沒有你需要<br/>下載的資料。 </span><br/><br/>        下載的軌跡檔案的格式是Google KML格式,如:“檔名.kml”。安裝 Google Earth後。雙擊KML<br/>檔案,會通過Google Earth工具開啟。<BR/>        "KML軌跡檔案"會將裝置的移動痕跡以紅線動態的描繪在Google地圖上。<br/>        <br/><br/>附註:下載 Google Earth 請點選 <a href="http://dl.google.com/earth/client/ge4/release_4_3/googleearth-win-plus-4.3.7284.3916.exe"><font color="blue">這裡</font></a> <br/>',
startPk:"開始回放",stop:"停止",bTime:["對不起!本系統暫不提供時間段跨度超過","天以上的統計資料查詢!請將查詢時間段跨度改為不超過"],playOverTip:["軌跡回放完畢!!時間從 ","到"],totalTime:"總時間",duration:"執行",kPerH:"公里/小時",
//globe
lang:"cn",googleKey:"http://ditu.google.cn/",
lng:"經度",lat:"緯度",latlng:"經緯度",
snew:"新貨",skt:"開通",sbk:"退貨",swx:"維修",stj:"停機",//銷售狀態
sdw:"定位狀態",sdw0:"未定位",sdw1:"已定位",p:"位置:",//定位狀態
srun0:"未上線",srun1:"離線",srun2:"靜止",srun3:"行駛",srun4:"快速行駛",srun5:"超速行駛",srun6:"全部",//執行狀態
date:"日期",time:"時間",y:"年",d:"天",h:"小時",m:"分",s:"秒",due:"到期時間",serviceYear:"服務年限",saleTime:"銷售時間",factoryTime:"出廠日期",activeTime:"開通日期",dwtime:"定位時間",heartTime:"心跳時間",sendtime:"傳送時間",utime:"訊號時間",
update0:"關閉更新",update1:"開啟更新",view:"全景",target:"目標",
mi:"米",km:"公里",

on:"開啟",off:"熄火",
msgtit0:"提示",msgtit1:"成功",msgtit2:"失敗",//彈出視窗提示資訊標題

//loading 資訊
updateSuc:"資料更新成功....",subvali:"正在驗證.....請等待...",loadfali:"資料載入失敗...請重試",fload:"正在載入資料....請稍候",leadin:"正在提交資料.....請等待...",inputName:"請輸入您要統計裝置的裝置名稱!",

//tips
ctimetip:"查詢的時間跨度不能大於 ",msgcon0:"請選擇",msgcon1:"IMEI號輸入有誤,請輸入6位以上數字!!",msgcon2:"請輸入要搜尋的裝置名",
nodata:"沒有查詢到資料",distime:"開始時間不能大於結束時間",terror:"時間輸入有誤",//提示資訊內容
imeivali:"IMEI號必須是15個字元長度的數字組成",imeitip:'IMEI號必須為15個字元長度的數字,匯入多個IMEI號用","號分隔',saleImeiTip:"IMEI號必須是由5-20個字元長度的數字組成",
passvali:"倆次輸入的密碼不一致,請重新輸入",selUTip:"選擇客戶",fsuc:"以下裝置匯入成功",pexist:"以下裝置已經存在",lfaluler:"IMEI號匯入失敗....",
companyNameTip:"客戶名稱必須不能為空白字元",addUsuc:"客戶新增<font color=red>成功</font>",logNameVali:"登陸名的第一個字元不能為數字",delSelfTip:"你無權刪除你自己的賬號",delUTip:"您確定要刪除該使用者嗎?",selectTarget:"請選擇裝置",selectCustom:"請選擇客戶",
resetpwdtip:"你確定要重置密碼嗎?",resetpwdfail:"重置密碼失敗,請重試.....",userExist:"該登陸名已經存在!請選擇其他使用者名稱!",addFali:"資料新增失敗",resetpwdsuc:"您現在的密碼是",
SimNumTip:"SIM卡號必須為長度小於20位的數字",carNumExistTip:"您輸入的車牌號碼在系統中已存在,請重新輸入",stattip:"請選擇里程統計的日期",carNumFormatTip:"車牌號格式錯誤",dealedtip:"請不要重複處理",
sucpwdtip:"密碼已更新",falipwdtip:"密碼更新失敗!!",sendzltip:"發指令前請再次確認登陸密碼",dealedsuc:"報警處理成功",maptip:"Google map暫不支援當前瀏覽器!",zoomMax:"已經到達最大縮放級別了",

proaccount:"裝置登陸號",
product:"產品",client:"客戶",type:"型別",sclient:"選中客戶",pro:"裝置",name:"名稱",status:"狀態",speed:"速度",account:"裝置短號",pimei:"IMEI號",
list:"列表",allp:"所有裝置",hidn:"隱藏裝置名",shown:"顯示裝置名",number:"號碼",

//button
promanage:"裝置管理",add:"新增",manage:"管理",search:"查詢",resetPwd:"重置密碼",updatepwd:"修改密碼",leadin:"匯入",delall:"刪除所有",del:"刪除",areaPlayBack:"區域回放",active:"銷售開通",
statLC:"里程統計",statCS:"超速統計",downgj:"下載軌跡",runct:"執行統計",pback:"回 放",track:"跟 蹤",searchw:"查詢報警記錄",zl:"指令",cutyd:"遠端斷油電",repyd:"遠端恢復油電",checkp:"查詢定位",checkr:"查詢指令記錄",simei:"按IMEI號搜",sname:"按裝置名搜",addCustom:"新增客戶",
ok:"確定",sub:"提交",cancel:"取消",rset:"重置",rload:"過載",searchpro:"裝置查詢",searchIMEI:"搜 索",sale:"銷售",enlarge:"放大地圖",clos:"關閉",more:"更多...",

//array
hangxiang: [ "正北向", "北向", "東北向偏北", "東北向", "東北向偏東", "正東向", "東向","東南向偏東", "東南向", "東南向偏南", "正南向", "南向", "西南向偏南", "西南向", "西南向偏西","正西向", "西向", "西北向偏西", "西北向", "西北向偏北" ],
wtype: ["正常","震動報警","斷電報警","強行關機報警","SOS求救","超速報警","超速報警","超速報警","超速報警","超速報警"],
backMess :{SEND_SUCCESS:"指令下發成功",SEND_FAIL:"指令下發失敗",PWD_ERROR:"密碼錯誤",NOT_CUSTOMER:"客戶不存在",USER_LEAVE:"裝置離線,不能發指令"},
cmdType :{DWXX:'定位指令',DYD:'斷油電指令',HFYD:'恢復油電指令'},
statusType :['網頁發出指令','閘道器收到指令','閘道器判斷不滿足傳送指令條件','裝置不線上','閘道器傳送指令','終端響應指令'],
warnData :[['所有報警', 'ALL'],['震動報警', '1'], ['斷電報警', '2'],['低電報警', '3'], ['SOS求救', '4'], ['超速報警', '5']],
warnDealWith :['未處理','已處理'],gradeDate :[['經銷商', '4'], ['最終客戶', '8']],

//words
stip:"裝置IMEI號/裝置名",logName:"登陸名",warn:"報警",cmd:"指令",response:"響應",mess:"資訊",idle:"停留",sign:"訊號",
start:" 開 始:",end:" 結 束:",sarea:"經過區域裝置",atit:"區域設定",map:"地圖",
owner:"所屬客戶",platf:"平臺費",oney:"一年期",threey:"三年期",otherp:"外掛平臺",remark:"備註資訊",pwd:"密碼",opwd:"舊密碼",npwd:"新密碼",rpwd:"確認密碼",cfirm:"確認",
course:"航向",operate:"操作",warntit:"報警資訊報表",leadout:" 匯出 ",stattime:"  統計日期  ",tmovement:"總里程(單位:Km)",toverspeed:"總超速次數", mileagetit:"里程統計報表",dealed:"處理",movement:"里程",
viewpos:"檢視位置",timelywarntit:"報警資訊",icon:"選擇圖示",format:"格式",phone:"聯絡電話",contact:"聯絡人",address:"地址",oSpeed:"超速",updateMsg:"更新資訊",
adduwait:"新增客戶資訊",addutit:"新增客戶",cardNum:"卡號",carNum:"車牌號",pCompany:"所屬客戶",updateUTit:"更新客戶資訊",grate:"級別",companyName:"客戶名稱",SuperCustom:"上級客戶",tagInfo:"裝置資訊",tagName:"裝置名",cmdDetail:"指令詳細資訊",inputTip:"請輸入裝置名/IMEI號"
}


underscore.js-v=1.0.1.1

/*
 * 通用指令碼庫
 * 引入目的:解決記憶體洩漏問題,提升指令碼執行效能。
 */
function _(id){
 return document.getElementById(id);
}
/*
 * @description 跨瀏覽器getElementsByClassName實現
 * @param searchClass  '{tag}.{className}'
 * @param node 共搜尋的的目標父節點
 */
_._ = function (searchClass, node) {
 var result = [], sc = searchClass.split('.'), tag;
 if(sc.length ===2){
  searchClass = sc[1];
  tag = sc[0]||'*';
 }else{
  return null;
 }
 if(document.getElementsByClassName){
  var nodes =  (node || document).getElementsByClassName(searchClass);
  for(var i=0 ;node = nodes[i++];){
   if(tag !== "*" && node.tagName === tag.toUpperCase()){
    result.push(node);
   }else{
    result.push(node);
   }
  }
    }else{
        if ( node == null )
                node = document;
        var els = node.getElementsByTagName(tag);
        var elsLen = els.length;
        var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
        for (i = 0, j = 0; i < elsLen; i++) {
   if ( pattern.test(els[i].className) ) {
    result[j] = els[i];
    j++;
   }
        }
    }
 return result;
};
/*
 * @description 判斷是否是IE,如果是返回具體版本號
 * @return IE的版本號,W3C系列返回undefined
 * */
_.isIE = (function(){
    var undef, v = 3,
        div = document.createElement('div'),
        all = div.getElementsByTagName('i');
    while (
        div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
        all[0]
    );
    return v > 4 ? v : undef;
}());
/*
 * @description 判斷是否是陣列
 */
_.isArray = function(o){
 return Object.prototype.toString.call(o) === '[object Array]';
};
/*
 * @description 批量設定樣式表
 * @param el HTML節點
 * @param cssText style樣式
 * @param overWrite 是否重寫現有節點style屬性,預設為false
 */
_.css = function (el,cssText,overWrite){
 if(el&&el.style){
  if(overWrite)
   el.style.cssText = cssText;
  else
   el.style.cssText += ';'+ cssText;
 }
};
/*
 * @description 動態插入樣式表到head
 * @param cssText css
 * @param id style節點id
 */
_.css.append = function(cssText,id){
 var css = document.createElement('style') ,head = document.head || document.getElementsByTagName("head")[0];
 if(id){
  css.setAttribute('id',id);
 }
    css.setAttribute('type', 'text/css');
 //IE
    if(css.styleSheet) {
        css.styleSheet.cssText = cssText;
    } else {
        css.appendChild(document.createTextNode(cssText));
    }
    head.appendChild(css);
};
/*
 * @description 切換樣式表,移除所有包含此樣式的元素;給當前節點加上此樣式
 * @param node 當前節點
 * @param clas 樣式表
 * @param context 移除樣式表元素的父節點
 */
_.css.toggle = function(node,cls,context){
 context = context || document.body;
 var clsArr = cls.split('.');
 if(clsArr.length !=2)return;
 var tag = clsArr[0], className = clsArr[1];
 var olds = _._(cls,context), len = olds.length, i = 0;
 for(;i<len;i++){
  olds[i].className = olds[i].className.replace(className,'');
 }
 var current = node.className;
 if(current.indexOf(className)== -1){
  node.className = current+ ' ' + className;
 }
};
_.dom = function(){};
/**
 * @description 呼叫此方法來保證插入節點後再設定節點的innerHTML,避免在IE中的記憶體洩漏
 */
_.dom.append = function(parent,tagName){
 var node = document.createElement(tagName);
 parent.appendChild(node);
 return node;
};
/*
 * @description 採用ext的處理方式,也可以對刪除的元素使用outerHTML='',但是此方法不通用,某些元素的outerHTML屬性只讀
 * @param n 要刪除的HTML節點
 */
_.dom.remove = function(n){
 var d;
 if(_.isIE){
        if(n && n.tagName != 'BODY'){
            d = d || document.createElement('div');
            d.appendChild(n);
            d.innerHTML = '';
        }
 }else{
     if(n && n.parentNode && n.tagName != 'BODY'){
         n.parentNode.removeChild(n);
     }
 }
};
/*
 * @description 移除要刪除節點的所有事件,防止IE記憶體洩漏
 * @param d 要刪除的節點
 */
_.dom.purdge = function(d){
    var a = d.attributes, i, l, n;
    if (a) {
        l = a.length;
        for (i = 0; i < l; i += 1) {
            n = a[i].name;
            if (typeof d[n] === 'function') {
                d[n] = null;
            }
        }
    }
    a = d.childNodes;
    if (a) {
        l = a.length;
        for (i = 0; i < l; i += 1) {
            _.dom.purdge(d.childNodes[i]);
        }
    }
};
_.ajax = function(){};
/******** JSONP輪詢記憶體洩漏 ********
 * 為IE新增重用的動態script標籤,標準瀏覽器無法重用script標籤
 * 重用的script標籤可能被佔用,也可能請求時傳送網路錯誤,因此需要新增額外的處理機制;
 * W3C瀏覽器JSONP沒有記憶體洩漏,所以onload完成後直接刪除即可。
 */
//TODO:為標準瀏覽器新增onerror統計超時請求,
(function(){
    //儲存超時或異常的JSONP請求
    _.ajax.TIMEOUT_REQUEST = [];
 if(_.isIE){
  //JSONP重用標籤的id
  _.ajax.SCRIPT_ID = 'ie_script_for_jsonp';
  //重用標籤是否被JSONP請求佔用
  _.ajax.SCRIPT_USED = false;
  //被佔用時JSONP請求等待的時間
  _.ajax.WAIT_TIME = 100;
  //超時設定
  _.ajax.TIMEOUT = 1500;

  //上次JSONP請求的時間
  _.ajax.LAST_USED_TIME = 0;
  var script = document.createElement('script'), head = document.head || document.getElementsByTagName('head')[0];
  script.setAttribute('id',_.ajax.SCRIPT_ID);
  script.onreadystatechange = function(){
   if (this.readyState == "loaded" || this.readyState == "complete"){
    _.ajax.SCRIPT_USED = false;
   }
  };
  head.appendChild(script);
 }
})();
/*
 * @description 輪詢JSONP請求呼叫,IE瀏覽器採用重用Script節點方式。
 * @param url 手動加上callback引數,自動追加了時間戳
 */
_.ajax.jsonp = function(url){
 var script, now = new Date().getTime(),
  requestUrl = url + (url.indexOf('?')>-1?'&timestamp=':'?timestamp=') + now,
  head = document.head || document.getElementsByTagName('head')[0];
 if(_.isIE){
  script = document.getElementById(_.ajax.SCRIPT_ID);
  //節點被佔用
  if(_.ajax.SCRIPT_USED){
   if(_.ajax.LAST_USED_TIME === 0)
    _.ajax.LAST_USED_TIME = now;
   //已經超時
   if((now - _.ajax.LAST_USED_TIME) > _.ajax.TIMEOUT){
    _.ajax.LAST_USED_TIME = now;
    if(_.ajax.TIMEOUT_REQUEST.length>=1000)
     _.ajax.TIMEOUT_REQUEST.length = 0;
    _.ajax.TIMEOUT_REQUEST.push(script.src.split('&timestamp=')[0]);
    script.src = requestUrl;
   //沒有超時則等待
   }else{
    setTimeout(function(){_.ajax.jsonp(url);},_.ajax.WAIT_TIME);
   }
  }else{
   _.ajax.SCRIPT_USED = true;
   _.ajax.LAST_USED_TIME = now;
   script.src = requestUrl;
  }
 }else{
  script = document.createElement('script');
  head.appendChild(script);
  script.onload = function(){
   this.onload = null;
   this.parentNode.removeChild(this);
  };
        script.onerror = function(){
            _.ajax.TIMEOUT_REQUEST.push(this.src);
        };
  script.src = requestUrl;
 }
};
/*
 * @description 獲取遠端指令碼,只適合載入一次的指令碼,輪詢請使用_.ajax.jsonp。JSONP請求預設加上時間戳;普通AJAX不加時間戳
 * @param callback JSONP載入指令碼的回撥函式
 * */
_.ajax.getScript = function(url,callback){
 var script, head = document.head || document.getElementsByTagName('head')[0], now = new Date().getTime();
 script = _.dom.append(head,'script');
 if(callback){
  if(url.indexOf("?")>-1){
   url = "&callback=" + callback ;
  }else{
   url = "?callback=" + callback ;
  }
 }
 //如果是JSONP
 if(url.indexOf('callback=')>0){
  url += "&timestamp=" + now;
 }
 script.src = url;
};
/*
 * @description 獲取多個遠端指令碼檔案,只適合載入一次。輪詢請使用_.ajax.jsonp
 * */
_.ajax.getScripts = function(urlArray){
 if(_.isArray(urlArray)){
  for(var index in urlArray){
   _.ajax.getScript(urlArray[index]);
  }
 }
};
/*
 * @description 類繼承,子類持有父類原型
 * @param child 子類
 * @param parent 父類
 */
_.extend =  function(child,parent) {
 var F = function() {};
 F.prototype = parent.prototype;
 child.prototype = new F();
 child.prototype.constructor = child;
 //hold parent prototype ref
 child.pp = parent.prototype;
};
/*
 * @description 複寫子類的方法,如果父類有該方法,增強匿名函式的引數與父類函式引數順序一致。如果增強函式有返回值,則預設返回。
 * @param className 類名
 * @param methodName 要複寫的方法名稱
 * @param extraFunc 額外執行的函式,上下文環境為className的例項
 */
_.extendM = function(className,methodName,extraFunc){
 //如果有父類且父類有同名的方法
 if(className.pp && className.pp[methodName]){
  className.prototype[methodName] = function(){
   var result = extraFunc.apply(this,arguments);
   className.pp[methodName].apply(this,arguments);
   return result;
  };
 }
 else{
  className.prototype[methodName] = function(){
   return extraFunc.apply(this,arguments);
  };
 }
};
_.trim = function(text){
 if(String.prototype.trim){
  return text == null ?"" :String.prototype.trim.call(text);
 }else{
  return text == null ?"" :text.toString().replace( /^\s+/, "" ).replace(  /\s+$/, "" );
 }
};
/*
 * @description from jquery.cookie.js
 * @param options {expires,path,domain,secure}
 */
_.cookie = function(name,value,options){
  if (typeof value != 'undefined') { // name and value given, set cookie
     options = options || {};
     if (value === null) {
         value = '';
         options.expires = -1;
     }
     var expires = '';
     if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
         var date;
         if (typeof options.expires == 'number') {
             date = new Date();
             date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
         } else {
             date = options.expires;
         }
         expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
     }
     var path = options.path ? '; path=' + options.path : '';
     var domain = options.domain ? '; domain=' + options.domain : '';
     var secure = options.secure ? '; secure' : '';
     document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
 } else { // only name given, get cookie
     var cookieValue = '';
     if (document.cookie && document.cookie != '') {
         var cookies = document.cookie.split(';');
         for (var i = 0; i < cookies.length; i++) {
             var cookie = _.trim(cookies[i]);
             // Does this cookie string begin with the name we want?
             if (cookie.substring(0, name.length + 1) == (name + '=')) {
                 cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                 break;
             }
         }
     }
     return cookieValue;
 }
};

popupmarker.js-v=1.0.1.1

PopupMarker.IS_BAIDU_MAP = typeof BMap !=='undefined';
PopupMarker.YPOS = 0;
PopupMarker.LEFT_TOP_HEIGHT = 7;
PopupMarker.YPOS2 = PopupMarker.YPOS + PopupMarker.LEFT_TOP_HEIGHT;
PopupMarker.POPUP_TBL = {
		leftTop : {"left" : 0,"top" : PopupMarker.YPOS,"width" : 19,"height" : PopupMarker.LEFT_TOP_HEIGHT},
		leftTopFill : {"left" : 16,"top" : 3,"width" : 4,"height" : 4},
		rightTop : {"left" : 19,"top" : PopupMarker.YPOS,"width" : 10,"height" : PopupMarker.LEFT_TOP_HEIGHT},
		rightTopImg : {"left" : -125,"top" : 0,"width" : 10,"height" : PopupMarker.LEFT_TOP_HEIGHT},
		centerTopFill : {"left" : 19,"top" : PopupMarker.YPOS,"width" : 0,"height" : PopupMarker.LEFT_TOP_HEIGHT},
		leftBody : {"left" : 11,"top" : PopupMarker.YPOS2,"width" : 8,"height" : 0},
		centerBodyFill : {"left" : 19,"top" : PopupMarker.YPOS2,"width" : 40,"height" : 15},
		rightBody : {"left" : 19,"top" : PopupMarker.YPOS2,"width" : 9,"height" : 0},
		leftBottom : {"left" : 0,"top" : PopupMarker.YPOS2,"width" : 20,"height" : 21},
		leftBottomImg : {"left" : 0,"top" : -13,"width" : 20,"height" : 21},
		leftBottomFill : {"left" : 16,"top" : 0,"width" : 4,"height" : 6},
		rightBottom : {"left" : 19,"top" : PopupMarker.YPOS2,"width" : 10,"height" : PopupMarker.LEFT_TOP_HEIGHT},
		rightBottomImg : {"left" : -125,"top" : -13,"width" : 10,"height" : PopupMarker.LEFT_TOP_HEIGHT},
		centerBottomFill : {"left" : 19,"top" : (PopupMarker.YPOS2 + (_.isIE ? -1 : 0)),"width" : 0,"height" : (6 + (_.isIE ? 1 : 0))}
};
PopupMarker.prototype =PopupMarker.IS_BAIDU_MAP?(new BMap.Overlay()):(new google.maps.OverlayView());
/*
 * @decription setMap填充覆蓋物到地圖放在最後一步,百度似乎有點問題
 * @param opts {map:goome.maps.Map,position:goome.maps.LatLng,text:string}
 */
function PopupMarker(opts) {
    this.ICON_WIDTH = opts.ICON_WIDTH||12;
    this.ICON_HEIGHT =opts.ICON_HEIGHT|| 20;
    this.map_ = opts.map;
    this.latlng_ = opts.position;
    this.icon_ = opts.icon;
    this.text_ = opts.text || "";
    this.showpop = opts.showpop || false;
    this.popupImgSrc_ = "images/1280.png";
    //是否已經執行過updatePopLayerText,在此函式結束時設定為true
    this.updatedPop = false;
	if(document.getElementById('dummyTextNode')) {
		this.dummyTextNode = document.getElementById('dummyTextNode');
	}
	else{
		var dummyTextNode = document.createElement("span");
		dummyTextNode.id = 'dummyTextNode';
		dummyTextNode.style.display = 'none';
		this.map_.getDiv().appendChild(dummyTextNode);
		this.dummyTextNode = dummyTextNode;
		dummyTextNode =null;
	}
	this.setMap(PopupMarker.IS_BAIDU_MAP?this.map_:this.map_._source);
};
//百度需要額外推薦一些方法
if(PopupMarker.IS_BAIDU_MAP){
	PopupMarker.prototype.initialize = function(map){
		var spanContainer = document.createElement("span");
	    this.container_ = document.createElement("div");
	    this.iconContainer = document.createElement("div");
	    
	    var panes = this.map_._source.getPanes();
	    panes.floatShadow.appendChild(spanContainer);
		spanContainer.appendChild(this.iconContainer);
		spanContainer.appendChild(this.container_);
		
	    this.iconContainer.style.width = this.ICON_WIDTH + "px";
	    this.iconContainer.style.height = this.ICON_HEIGHT + "px";
	    this.iconContainer.innerHTML = "<img src='" + this.icon_ + "'>";
	    this.iconContainer.style.position = "absolute";
	    
	    //panes.floatPane.appendChild(this.container_);
	    this.container_.style.position = "absolute";
	    if (!this.showpop) this.container_.style.visibility = "hidden";
	    this.makeNormalPopup_();
		return spanContainer;
		//this.onAdd();
	};
	PopupMarker.prototype.setMap = function(obj){
		if(obj==null)
			this.map_._source.removeOverlay(this);
		else{
			obj._source.addOverlay(this);
		}
	};
}
PopupMarker.prototype.onAdd = function() {
    this.container_ = document.createElement("div");
    this.iconContainer = document.createElement("div");
    var panes = this.getPanes?this.getPanes():this.map_._source.getPanes();
    panes.floatShadow.appendChild(this.iconContainer);
    panes.floatPane.appendChild(this.container_);
    
    this.iconContainer.style.width = this.ICON_WIDTH + "px";
    this.iconContainer.style.height = this.ICON_HEIGHT + "px";
    this.iconContainer.innerHTML = "<img src='" + this.icon_ + "'>";
    this.iconContainer.style.position = "absolute";

    this.container_.style.position = "absolute";
    if (!this.showpop) this.container_.style.visibility = "hidden";
    this.makeNormalPopup_();
};
PopupMarker.prototype.draw = function() {
    this.redrawNormalPopup_(this.text_);
};
PopupMarker.prototype.onRemove = function() {
	_.dom.remove(this.container_);
	_.dom.remove(this.iconContainer);
};

PopupMarker.prototype.makeNormalPopup_ = function() {
	var frag = document.createDocumentFragment();
	//0
    var leftTop_ = this.makeImgDiv_(this.popupImgSrc_, PopupMarker.POPUP_TBL.leftTop);
    leftTop_.appendChild(this.fillDiv_(PopupMarker.POPUP_TBL.leftTopFill));
    frag.appendChild(leftTop_);
	//1
    var leftBody_ = this.fillDiv_(PopupMarker.POPUP_TBL.leftBody);
	_.css(leftBody_ ,'border-width:0 0 0 1px;border-style:none none none solid;border-color:#000');
    frag.appendChild(leftBody_);
	//2
    var leftBottom_ = this.makeImgDiv_(this.popupImgSrc_, PopupMarker.POPUP_TBL.leftBottomImg);
    leftBottom_.appendChild(this.fillDiv_(PopupMarker.POPUP_TBL.leftBottomFill));
	_.css(leftBottom_ ,'left:'+PopupMarker.POPUP_TBL.leftBottom.left +'px;top:'+PopupMarker.POPUP_TBL.leftBottom.top +'px;width:'+PopupMarker.POPUP_TBL.leftBottom.width +'px;height:'+PopupMarker.POPUP_TBL.leftBottom.height +'px;');
    frag.appendChild(leftBottom_);
	//3
    var bodyContainer_ = document.createElement("div");
	_.css(bodyContainer_ ,'position:absolute;background-color:#fff;overflow:hidden;left:'+PopupMarker.POPUP_TBL.centerBodyFill.left +'px;top:'+PopupMarker.POPUP_TBL.centerBodyFill.top +'px;width:'+PopupMarker.POPUP_TBL.centerBodyFill.width +'px;height:'+PopupMarker.POPUP_TBL.centerBodyFill.height +'px;');
    frag.appendChild(bodyContainer_);
	//4
    var rightTop_ = this.makeImgDiv_(this.popupImgSrc_, PopupMarker.POPUP_TBL.rightTopImg);
	_.css(rightTop_ ,'left:'+PopupMarker.POPUP_TBL.rightTop.left +'px;top:'+PopupMarker.POPUP_TBL.rightTop.top +'px;width:'+PopupMarker.POPUP_TBL.rightTop.width +'px;height:'+PopupMarker.POPUP_TBL.rightTop.height +'px;');
    frag.appendChild(rightTop_);
	//5
    var rightBottom_ = this.makeImgDiv_(this.popupImgSrc_, PopupMarker.POPUP_TBL.rightBottomImg);
	_.css(rightBottom_ ,'left:'+PopupMarker.POPUP_TBL.rightBottom.left +'px;top:'+PopupMarker.POPUP_TBL.rightBottom.top +'px;width:'+PopupMarker.POPUP_TBL.rightBottom.width +'px;height:'+PopupMarker.POPUP_TBL.rightBottom.height +'px;');
    frag.appendChild(rightBottom_);
	//6
    var rightBody_ = this.fillDiv_(PopupMarker.POPUP_TBL.rightBody);
	_.css(rightBody_ ,'border-width:0 1px 0 0;border-style:none solid none none;border-color:#000');
    frag.appendChild(rightBody_);
	//7
    var centerBottom_ = this.fillDiv_(PopupMarker.POPUP_TBL.centerBottomFill);
	_.css(centerBottom_ ,'border-width:0 0 1px 0;border-style:none none solid none;border-color:#000');
    frag.appendChild(centerBottom_);
	//8
    var centerTop_ = this.fillDiv_(PopupMarker.POPUP_TBL.centerTopFill);
	_.css(centerTop_ ,'border-width:1px 0 0 0;border-style:solid none none none;border-color:#000');
    frag.appendChild(centerTop_);
	
	this.container_.appendChild(frag);
};
PopupMarker.prototype.redrawNormalPopup_ = function(text) {
    if (this.beforeNormalPopupText_ !== text) {
		var bodyContainer_ = this.container_.children[3],
			leftBottom_ = this.container_.children[2],
			leftBody_ = this.container_.children[1],
			rightTop_ = this.container_.children[4],
			rightBottom_ = this.container_.children[5],
			rightBody_ = this.container_.children[6],
			centerBottom_ = this.container_.children[7],
			centerTop_ = this.container_.children[8];
        bodyContainer_.innerHTML = text;
        if (!_.isIE && text) {
            if (bodyContainer_.firstChild.nodeType === 1) {
                bodyContainer_.firstChild.style.margin = 0;
            }
        }
        var offsetBorder = _.isIE ? 2: 0;
        var cSize = this.getHtmlSize_(text);
        var rightX = PopupMarker.POPUP_TBL.leftTop.width + cSize.width;
        leftBottom_.style.top = (cSize.height + PopupMarker.POPUP_TBL.leftBody.top) + "px";
        leftBody_.style.height = cSize.height + "px";
        bodyContainer_.style.width = cSize.width + "px";
        bodyContainer_.style.height = cSize.height + "px";
        bodyContainer_.style.top = PopupMarker.POPUP_TBL.leftBody.top;
        rightTop_.style.left = rightX + "px";
        rightBottom_.style.left = rightTop_.style.left;
        rightBottom_.style.top = leftBottom_.style.top;
        rightBody_.style.left = rightX + "px";
        rightBody_.style.height = leftBody_.style.height;
        centerBottom_.style.top = leftBottom_.style.top;
        centerBottom_.style.width = cSize.width + "px";
        centerTop_.style.width = cSize.width + "px";
        this.size_ = {
            "width": (rightX + PopupMarker.POPUP_TBL.rightTop.width),
            "height": (cSize.height + PopupMarker.POPUP_TBL.leftTop.height + PopupMarker.POPUP_TBL.leftBottom.height)
        };
        this.container_.style.width = this.size_.width + "px";
        this.container_.style.height = this.size_.height + "px";
    }
    bodyContainer_ = leftBottom_ = leftBody_ = rightTop_ = rightBottom_ = rightBody_ = centerBottom_ = centerTop_ = null;
    this.setPosition(this.latlng_);
    this.beforeNormalPopupText_ = text;
};

/*
 * @description 獲得文字內容的基本寬度和高度,如果遇見marker沒有正確的顯示出來,很有可能是這裡出問題了
 * @return goome.maps.Size
 */
PopupMarker.prototype.getHtmlSize_ = function(html) {
    var size = {};
	this.d