﻿/*
 * ess_map_mod.js V1.1.9.0202
 * 此脚本扩展了GMap API v2地图客户端
 * V1.1.9在IE6/7/8(Windows XP/2003/Vista/2008)、Firefox 2/3(Windows XP/2003/Vista/2008、Ubuntu Linux 8.10)下测试通过
 *
 * 需要预先定义好_mRootPath（应用程序根路径）、_mClntLibPath（客户端脚本库路径）、_mStaticPath（背景及图标等资源文件存放路径）这几个全局变量
 *
 * 代码命名方法：
 * 1. 类名、方法、属性、变量采用Java命名方案，即类名以大写字母开头，方法、属性、变量以小写字母开头；
 * 2. 公共方法、属性的命名不遵循匈牙利命名法；公共方法的参数、私有成员变量、私有函数的命名遵循匈牙利命名法；函数级局部变量采用短命名；
 * 3. 私有成员变量、私有函数以下划线开头；
 * 4. 静态变量（含常数、枚举）全部大写；
 * 5. 全局非静态变量的命名与类的私有成员变量命名的唯一不同就是，全局变量以“g_”开头。
*/

var GIS_TOOL_PAN = 1;	//漫游
var GIS_TOOL_RECT_ZOOM_IN = 11;	//拉框放大
var GIS_TOOL_RECT_ZOOM_OUT = 13;	//拉框缩小
var GIS_TOOL_MAGNIFIER = 19;	//地图放大镜
var GIS_TOOL_LABEL = 21;	//标注
var GIS_TOOL_MEAS_DISTANCE = 31;	//测距
var GIS_TOOL_MEAS_SQUARE = 32; //面积量算
var GIS_TOOL_RECT_SELECT = 51;//拉框选择

var MAX_ZOOM_LEVEL = 17;	//最大放大级别
var MIN_ZOOM_LEVEL = 8;	//最小缩小级别

function EwMapControl (sInstanceName, oMapInstance, aMapControls) {
	//**“私有成员变量”开始
	var _eCurGisTool = GIS_TOOL_PAN;	//当前GIS工具
	var _oMouseLatLng = null;	//当前鼠标位置的经纬度对象
	var _oMapCoverDiv = null;	//拉框覆盖层对象
	var _iOriEventX = 0;
	var _iOriEventY = 0;
	var _iCurEventX = 0;
	var _iCurEventY = 0;
	var _oMapOverviewDiv = null;
	var _oRulerControl = null;
	var _oReturnToPanControl = null;
	var _oMagnifierMap = null;	//用于地图放大镜的地图实例
	var _oMagnifierBorder = null;	//放大镜边框对象
	var _bCoordEncoded = false; //折线不启用编码
	var _bIsShowCoordInStatus = false; //是否在浏览器状态栏显示经纬度
	var _bIsLeftInRightOutEnabled = false; //在漫游状态下，是否启用左键放大右键缩小
	var _bDoubleClickZoomEnabled = false;
	var _bGIconDel = false;
	//**“私有成员变量”结束

	//**私有静态变量、常量开始
	var DRAG_RECT_DIV_NAME = "layDragRect";  //拉框矩形的对象的ID
	var DRAG_RECT_PROMPT_DIV_NAME = "layDragRectPrompt";	//拉框提示对象的ID
	var MAGNIFIER_ZOOM_DELTA = 1;	//地图放大镜比当前地图多出的放大级别
	var IE_VERSION = _fCheckBrowser();	//IE浏览器版本
	//**私有静态变量结束
	
	//**属性开始
	this.map = oMapInstance;	//地图客户端实例
	this.ieVersion = IE_VERSION;
	//**属性结束

	//**方法开始
	this.setCenter = function(latlng, level) {
		oMapInstance.setCenter(latlng, level);

		if (!_bGIconDel) {
			var div = oMapInstance.getContainer();
			if (div.childNodes && 3 <= div.childNodes.length) {	//删除“Powered By Goole”标志
				div.removeChild(div.childNodes[2]);
				div.childNodes[div.childNodes.length - 1].style.left = eval(parseInt(div.childNodes[div.childNodes.length - 1].style.left) - 62) + "px"; //将比例尺信息左移
				_bGIconDel = true;
			}
		}
	};

	this.setShowCoordInStatus = function(val) { _bIsShowCoordInStatus = val; }; //设置是否在状态栏显示经纬度坐标
	this.getShowCoordInStatus = function() { return _bIsShowCoordInStatus; }; //获取是否在状态栏显示经纬度坐标

	this.getLeftInRightOutZoom = function() { return _bIsLeftInRightOutEnabled; };
	this.setLeftInRightOutZoom = function(val) {
		if (val) {	//启用
			_bDoubleClickZoomEnabled = oMapInstance.doubleClickZoomEnabled(); //保存原双击放大设置
			if (_bDoubleClickZoomEnabled) {
				oMapInstance.disableDoubleClickZoom(); //禁止GMap固有的双击放大功能
			}
		}
		else {	//禁用
			if (_bDoubleClickZoomEnabled) {
				oMapInstance.enableDoubleClickZoom(); //恢复原来的双击放大设置
			}
		}

		_bIsLeftInRightOutEnabled = val;
	}
	
	this.getGisTool = function () { return _eCurGisTool; };	//获取当前GIS工具
	this.setGisTool = function(eGisTool) {	//设置工具
		_eCurGisTool = eGisTool;

		switch(eGisTool) {
			case GIS_TOOL_PAN:	//漫游
			case GIS_TOOL_LABEL:	//点标注工具
				if (!oMapInstance.draggingEnabled()) {
					oMapInstance.enableDragging();
				}
				if (!oMapInstance.scrollWheelZoomEnabled()) {
					oMapInstance.enableScrollWheelZoom();
				}
				_vHideMapCover();
				if (_oRulerControl) {
					_oRulerControl.reset();
					_oRulerControl.setEnabled(false);
					oMapInstance.removeControl(_oRulerControl);
				}
				_vHideMagnifierMap();
				break;
			case GIS_TOOL_RECT_ZOOM_IN:	//拉框放大及点击中心点放大
				_vCreateMapCover();
				_oMapCoverDiv.style.display = "block";
				_oMapCoverDiv.style.cursor = "url('" + _mStaticPath + "cur/129." + ((IE_VERSION>3) ? "cur')" : "png'),move");
				if (oMapInstance.scrollWheelZoomEnabled()) {
					oMapInstance.disableScrollWheelZoom();
				}
				if (_oRulerControl) {
					_oRulerControl.reset();
					_oRulerControl.setEnabled(false);
					oMapInstance.removeControl(_oRulerControl);
				}
				_vHideMagnifierMap();
				break;
			case GIS_TOOL_RECT_ZOOM_OUT:	//拉框缩小及点击中心点缩小
				_vCreateMapCover();
				_oMapCoverDiv.style.display = "block";
				_oMapCoverDiv.style.cursor = "url('" + _mStaticPath + "cur/130." + ((IE_VERSION>3) ? "cur')" : "png'),move");
				if (oMapInstance.scrollWheelZoomEnabled()) {
					oMapInstance.disableScrollWheelZoom();
				}
				if (_oRulerControl) {
					_oRulerControl.reset();
					_oRulerControl.setEnabled(false);
					oMapInstance.removeControl(_oRulerControl);
				}
				_vHideMagnifierMap();
				break;
            case GIS_TOOL_RECT_SELECT: //拉框选择
                _vCreateMapCover();
                _oMapCoverDiv.style.display = "block";
                _oMapCoverDiv.style.cursor = "url('" + _mStaticPath + "cur/rect." + ((IE_VERSION > 3) ? "cur')" : "png'),move");
                if (oMapInstance.scrollWheelZoomEnabled()) {
                    oMapInstance.disableScrollWheelZoom();
                }
                if (_oRulerControl) {
                    _oRulerControl.reset();
                    _oRulerControl.setEnabled(false);
                    oMapInstance.removeControl(_oRulerControl);
                }
                _vHideMagnifierMap();
                break;
			case GIS_TOOL_MAGNIFIER:	//地图放大镜
				if (oMapInstance.scrollWheelZoomEnabled()) {
					oMapInstance.disableScrollWheelZoom();
				}
				if (_oRulerControl) {
					_oRulerControl.reset();
					_oRulerControl.setEnabled(false);
					oMapInstance.removeControl(_oRulerControl);
				}
				_vHideMapCover();
				if (_oRulerControl) {
					_oRulerControl.reset();
					_oRulerControl.setEnabled(false);
					oMapInstance.removeControl(_oRulerControl);
				}
				_vCreateMagnifierMap();
				break;
			case GIS_TOOL_MEAS_DISTANCE:	//测距
				if (_oRulerControl) {
					oMapInstance.removeControl(_oRulerControl);
				}
				else {
					_oRulerControl = new GRulerControl();
				}
				oMapInstance.addControl(_oRulerControl);
				_oRulerControl.reset();
				_oRulerControl.setEnabled(true);
				_oRulerControl.setEsosoControl(this);
				if (!oMapInstance.draggingEnabled()) {
					oMapInstance.enableDragging();
				}
				if (!oMapInstance.scrollWheelZoomEnabled()) {
					oMapInstance.enableScrollWheelZoom();
				}
				_vHideMapCover();
				_vHideMagnifierMap();
				break;
			default:
				break;
		}
	}
	
	this.getDistance = function (j1, w1, j2, w2) {
		var dParam = 4.848136728395E-6 * 3600;
		var a = 6378245.0;
		var b = 6356863.0188;
		var m_fRadius = (a+b+a)/3.0;

		var PC, PA, AC, AB, PQ, QA;
		var cos_BPC,cos_AOC,cos_APC,cos_APB,cos_AOB;
		var center_corner;
		var longitude_t12;
		var latitude_t12;

		var m_pArcLen, circle_distance;
		m_pArcLen = 0;
			
		longitude_t12 = Math.abs(j1 - j2)*dParam;
		latitude_t12  = Math.abs(w1 - w2)*dParam;

		cos_BPC = Math.cos(longitude_t12);
		cos_AOC = Math.cos(latitude_t12);

		AC = Math.sqrt(2 * m_fRadius * m_fRadius * (1 - cos_AOC));

		PC = m_fRadius * Math.cos(w2*dParam);
		QA = m_fRadius * Math.cos(w1*dParam);
		PQ = Math.abs(m_fRadius * Math.sin(w2*dParam) - m_fRadius * Math.sin(w1*dParam));
		PA = Math.sqrt(QA*QA + PQ*PQ);

		cos_APC = (PA*PA + PC*PC - AC*AC) / (2 * PA * PC);
		cos_APB = cos_APC*cos_BPC;

		AB = Math.sqrt(PA*PA + PC*PC - 2*PA*PC*cos_APB);

		cos_AOB = (2 * (m_fRadius*m_fRadius) - AB * AB) / (2*m_fRadius*m_fRadius);

		center_corner = Math.acos( cos_AOB );
		circle_distance = m_fRadius * center_corner ;

		m_pArcLen += circle_distance;

		return Math.round(Math.abs(m_pArcLen) * 100) / 100;
	}
	
	//根据传入的视野计算合适的缩放等级
	this.getZoomLevel = function(fDistance) {
		var level3 = 2000.0 / 115 * 800;
		var level4 = 1000.0 / 115 * 800;
		var level5 = 500.0 / 115 * 800;
		var level6 = 200.0 / 92 * 800;
		var level7 = 100.0 / 92 * 800;
		var level8 = 50.0 / 92 * 800;

		if (fDistance >= level4 && fDistance < level3) {
			return 12;
		}
		else if (fDistance >= level5 && fDistance < level4) {
			return 13;
		}
		else if (fDistance >= level6 && fDistance < level5) {
			return 14;
		}
		else if (fDistance >= level7 && fDistance < level6) {
			return 15;
		}
		else if (fDistance >= level8 && fDistance < level7) {
			return 16;
		}
		else if (fDistance < level8) {
			return 17;
		}
		else {
			return 11;
		}
	}
	
	this.decodeLine = function(encoded) {
		var len = encoded.length;
		var index = 0;
		var array = [];
		var lat = 0;
		var lng = 0;

		while (index < len) {
			var b;
			var shift = 0;
			var result = 0;
			do {
				b = encoded.charCodeAt(index++) - 63;
				result |= (b & 0x1f) << shift;
				shift += 5;
			} while (b >= 0x20);
			var dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
			lat += dlat;

			shift = 0;
			result = 0;
			do {
				b = encoded.charCodeAt(index++) - 63;
				result |= (b & 0x1f) << shift;
				shift += 5;
			} while (b >= 0x20);
			var dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
			lng += dlng;

			array.push([lat * 1e-5, lng * 1e-5]);
		}

		return array;
	}

	this.decodeLevels = function(encoded) {
		var levels = [];

		for (var pointIndex = 0; pointIndex < encoded.length; ++pointIndex) {
			var pointLevel = encoded.charCodeAt(pointIndex) - 63;
			levels.push(pointLevel);
		}

		return levels;
	}
	
	//根据传入的坐标数组计算合适的中心点坐标和缩放等级
	//aPosnData - 字符串二维数组，格式[[纬度1,经度1],[纬度2,经度2],...]
	this.getLevelAndCenter = function(aPosnData) {
	    var center = new GLatLng(24.518, 118.109);
	    var level = 12;

	    if ("object" == typeof (aPosnData) && 0 < aPosnData.length && 2 == aPosnData[0].length) {
	        var tmpx = parseFloat(aPosnData[0][1]);
	        var tmpy = parseFloat(aPosnData[0][0]);
	        var maxx = tmpx;
	        var maxy = tmpy;
	        var minx = tmpx;
	        var miny = tmpy;

	        for (var i = 1; i < aPosnData.length; i++) {
	            tmpx = parseFloat(aPosnData[i][1]);
	            tmpy = parseFloat(aPosnData[i][0]);

	            if (tmpx > maxx) {
	                maxx = tmpx;
	            }
	            if (tmpy > maxy) {
	                maxy = tmpy;
	            }

	            if (tmpx < minx) {
	                minx = tmpx;
	            }
	            if (tmpy < miny) {
	                miny = tmpy;
	            }
	        }

	        center = new GLatLng(miny + (maxy - miny) / 2, minx + (maxx - minx) / 2);

	        var zoomToBounds = new GLatLngBounds(new GLatLng(miny, minx), new GLatLng(maxy, maxx));
	        level = oMapInstance.getBoundsZoomLevel(zoomToBounds);
	    }

	    return { center: center, level: level };
	}
	
	//根据传入的坐标数组计算合适的中心点坐标和缩放等级
	//aPosnData - 浮点型二维数组，格式[[经度1,纬度1],[经度2,纬度2],...]
	this.getLevelAndCenter2 = function (aPosnData) {
		var center = new GLatLng(24.518, 118.109);
		var level = 12;

		if ("object" == typeof(aPosnData) && 0 < aPosnData.length) {
			var tmpx = aPosnData[0][0];
			var tmpy = aPosnData[0][1];
			var maxx = tmpx;
			var maxy = tmpy;
			var minx = tmpx;
			var miny = tmpy;

			for (var i = 1; i < aPosnData.length; i++) {
				tmpx = aPosnData[i][0];
				tmpy = aPosnData[i][1];

				if (tmpx > maxx) {
					maxx = tmpx;
				}
				if (tmpy > maxy) {
					maxy = tmpy;
				}

				if (tmpx < minx) {
					minx = tmpx;
				}
				if (tmpy < miny) {
					miny = tmpy;
				}
			}

			center = new GLatLng(miny + (maxy - miny) / 2, minx + (maxx - minx) / 2);

			var zoomToBounds = new GLatLngBounds(new GLatLng(miny, minx), new GLatLng(maxy, maxx));
			level = oMapInstance.getBoundsZoomLevel(zoomToBounds);
		}
		
		return { center : center, level : level };
	}
	
	//根据传入的折线编码计算合适的中心点坐标和缩放等级
	this.getLevelAndCenterByEncoded = function (asEncoded) {
		var asEncodedYX = [asEncoded.length];
		var asEncodedLevel = [asEncoded.length];
		var aPosnData = [];
		var aCountData = [];
		var level = oMapInstance.getZoom();
		var aTmp;
		
		for(var i=0; i<asEncoded.length; i++) {
			aTmp = this.decodeLine(asEncoded[i]);

			aCountData[i] = aTmp.length;
			for(var j=0; j<aTmp.length; j++) {
				aPosnData[aPosnData.length] = aTmp[j];
			}
			
			var encoded_points = "";
			var encoded_levels = "";
			var plat = 0;
			var plng = 0;
			for(var j=0; j<aTmp.length; j++) {
				var point = aTmp[j];
				var lat = point[1];
				var lng = point[0];

				var late5 = Math.floor(lat * 1e5);
				var lnge5 = Math.floor(lng * 1e5);

				dlat = late5 - plat;
				dlng = lnge5 - plng;

				plat = late5;
				plng = lnge5;

				encoded_points += encodeSignedNumber(dlat) + encodeSignedNumber(dlng);
				encoded_levels += encodeNumber(level);
			}

			asEncodedYX[i] = encoded_points;
			asEncodedLevel[i] = encoded_levels;
		}

		var cl = this.getLevelAndCenter2(aPosnData);
		
		return { center : cl.center, level : cl.level, encodedPoints : asEncodedYX, encodedLevels : asEncodedLevel };
	}
	
	this.getMouseLatLng = function () { return _oMouseLatLng; };	//获取当前鼠标位置的经纬度对象
	
	this.resizeTo = function (w, h) {   //改变地图大小
		var div = oMapInstance.getContainer();
		div.style.width = w + "px";
		div.style.height = h + "px";
		oMapInstance.checkResize();
	}

	this.drawPolyLineByEncoded = function (coords, color, weight, opacity) {  //画线
		var cl = this.getLevelAndCenterByEncoded(coords);

		for (var j=0; j<cl.encodedPoints.length; j++) {
			document.overlay = GPolyline.fromEncoded({color: color, weight: weight, opacity : opacity, points: cl.encodedPoints[j], zoomFactor: 32, levels: cl.encodedLevels[j], numLevels: 4});
			oMapInstance.addOverlay(document.overlay);
		}

		oMapInstance.setCenter(cl.center, cl.level);
	}
	
	this.drawPolyLine = function (coords, color, weight, opacity) {  //画线
		if (0 != coords.length) {
			var points = [];
			var cs = [];
			
			for(var j=0; j<coords.length; j++) {
				cs = coords[j];
										
				if (_bCoordEncoded) {
					createPoint(points, cs[1], cs[0], oMapInstance.getZoom());
				}
				else {
					points[j] = new GLatLng(cs[1], cs[0]);
				}
			}

			if (_bCoordEncoded) {
				createEncodings(oMapInstance, points, color, weight, opacity);
			}
			else {
				var polyline = new GPolyline(points, color, weight, opacity, {clickable : false, geodesic : false});
				oMapInstance.addOverlay(polyline);
			}
		}
	}
	//**方法结束

	//**“私有方法”开始
	function _vHideMapCover () {
		_oMapOverviewDiv = $("map_overview");

		if (_oMapOverviewDiv && 
			_oMapOverviewDiv.lastChild && 
			_oMapOverviewDiv.lastChild.firstChild && 
			"-443px" == _oMapOverviewDiv.lastChild.firstChild.style.top
		) {
			_oMapOverviewDiv.lastChild.style.display = "block";

			if (Prototype.Browser.IE) {
				_oMapOverviewDiv.lastChild.click();
			}
			else {
				var e = document.createEvent("MouseEvents");
				e.initEvent("click", true, true);
				_oMapOverviewDiv.lastChild.dispatchEvent(e);
			}
		}

		var node = oMapInstance.getContainer();
		if (node.childNodes && 2<=node.childNodes.length) {	//重新显示被隐藏的版权信息
			node.childNodes[1].style.display = "block";
		}
		if (node.childNodes && 4 <= node.childNodes.length) {
			node.childNodes[3].style.display = "block";	//重新显示缩放滑杆
		}

		if (_oMapCoverDiv) {
			_oMapCoverDiv.style.display = "none";
		}
		
		if (null != _oReturnToPanControl) {
			oMapInstance.removeControl(_oReturnToPanControl);
			_oReturnToPanControl = null;
		}

		_vHideDragRectPrompt();
	}

	function _vHideControls() {
		_oMapOverviewDiv = $("map_overview");

		if (_oMapOverviewDiv && 
			_oMapOverviewDiv.lastChild && 
			_oMapOverviewDiv.lastChild.firstChild
		) {
			if ("-428px" == _oMapOverviewDiv.lastChild.firstChild.style.top)
			{
				if (Prototype.Browser.IE) {
					_oMapOverviewDiv.lastChild.click();
				}
				else {
					var e = document.createEvent("MouseEvents");
					e.initEvent("click", true, true);
					_oMapOverviewDiv.lastChild.dispatchEvent(e);
				}
			}
			
			_oMapOverviewDiv.lastChild.style.display = "none";
		}

		var node = oMapInstance.getContainer();
		if (node.childNodes && 2<=node.childNodes.length) {	//隐藏版权信息
			node.childNodes[1].style.display = "none";
		}
		if (node.childNodes && 4 <= node.childNodes.length) {
			node.childNodes[3].style.display = "none";	//隐藏缩放滑杆
		}
		
		if (null == _oReturnToPanControl) {
			_oReturnToPanControl = new GReturnToPanControl();
		}
		oMapInstance.addControl(_oReturnToPanControl);
	}

	function _vCreateMapCover() {	//拉框覆盖层对象
		_vHideControls();

		if (null == _oMapCoverDiv) {
			var div = null;
			try {
				div = document.createElement("<div style=\"filter:\alpha(opacity=50)\">");
			}
			catch (e)
			{
				div = document.createElement("div");
				div.style.opacity = 0.5;
			}
			div.id = "dragZoomMapCover";
			div.style.position = "absolute";
			div.style.display = "none";
			div.style.overflow = "hidden";
			div.style.zIndex = 101;

			var mapPosition = _oGetElementPosition(oMapInstance.getContainer());
			var mapSize = oMapInstance.getSize();
			div.style.left = "0px";
			div.style.top = "0px";
			div.style.width = mapSize.width + "px";
			div.style.height = mapSize.height + "px";

			var img = document.createElement("img");
			img.src = _mStaticPath + "transparent.gif";
			img.style.width = mapSize.width + "px";
			img.style.height = mapSize.height + "px";
			img.alt = "";
			img.onmousedown = function () { return false; };
			div.appendChild(img);

			div.appendChild(document.createElement("div"));

			oMapInstance.getContainer().appendChild(div);
			_oMapCoverDiv = div;
		}
	}

	function _oGetElementPosition(oElmt) {
	  var x = oElmt.offsetLeft;
	  var y = oElmt.offsetTop;
	  var parent = oElmt.offsetParent;
	  while (null != parent) {
		x += parent.offsetLeft;
		y += parent.offsetTop;

		parent = parent.offsetParent;
	  }

	  return { pixelLeft : x, pixelTop : y };
	}

	function _vResizeDragRect(oContainer, iOriginX, iOriginY, iEndX, iEndY) {
		if (isNaN(iOriginX) || isNaN(iOriginY) || isNaN(iEndX) || isNaN(iEndY)) {
			return;
		}

		oContainer.style.display = "block";
		
		var div = $(DRAG_RECT_DIV_NAME);
		if (div) {
			var width = iEndX - iOriginX;
			var height = iEndY - iOriginY;

			div.style.left = eval((width > 0) ? iOriginX : iEndX) + "px";
			div.style.top = eval((height > 0) ? iOriginY : iEndY) + "px";
			div.style.width = Math.abs(width) + "px";
			div.style.height = Math.abs(height) + "px";
			div.style.display = "block";
		}
	}

	function _vHiddenDragRect(oContainer) {
		var div = $(DRAG_RECT_DIV_NAME);

		if (div && oContainer) {
			oContainer.childNodes[1].removeChild(div);
		}
	}

	function _vDisplayDragRect(oContainer) {
		var div = $(DRAG_RECT_DIV_NAME);

		if (div) {
			_vResizeDragRect(oContainer, -1, -1, -1, -1);
		} else {
			if (IE_VERSION >= 5.5 && IE_VERSION < 8) {
				var html = '<v:Rect id="' + DRAG_RECT_DIV_NAME + '" style="position:absolute;width:0px;height:0px;left:0px;top:0px;z-index:2;z-index:2" Filled="true" StrokeColor="#ff0000" StrokeWeight="3px"></v:Rect>';
				oContainer.childNodes[1].innerHTML = html;
			}
			else {
				div = document.createElement("div");
				div.id = DRAG_RECT_DIV_NAME;
				div.style.backgroundColor = "#ffffff";
				div.style.opacity = 0.6;
				div.style.position = "absolute";
				div.style.border = "3px solid #ff0000";
				div.style.width = "0px";
				div.style.height = "0px";
				div.style.left = "0px";
				div.style.top = "0px";
				div.style.zIndex = 2;
				oContainer.childNodes[1].appendChild(div);
			}

			oContainer.style.display = "block";
		}
	}

	function _fCheckBrowser() {
		if(Prototype.Browser.IE) {
			strVersion = navigator.appVersion;

			if(strVersion.indexOf('MSIE 4') != -1)
				return 4;
			else if(strVersion.indexOf('MSIE 5') != -1) {
				if(strVersion.indexOf('MSIE 5.5') != -1)
					return 5.5;
				else
					return 5;
			}
			else {
				var re =/MSIE \b(\d\.*\d*);/gi;
				var ary = re.exec(strVersion);

				return new Number(RegExp.$1);
			}
		}

		else return 3;
	}

	function _oGetEventPosn(evt) {
		var x, y;

		if (evt.pageX) {	  //Firefox
			x = evt.pageX;
			y = evt.pageY;
		}
		else if (evt.clientX) {   //IE
			var body = document.documentElement || document.body;
			x = evt.clientX + body.scrollLeft;
			y = evt.clientY + body.scrollTop;
		}

		return { x : x, y : y};
	}

	function _aGetMinAndSec(dCoordinate) {
		var minutes = (dCoordinate - Math.floor(dCoordinate)) * 60;
		var secounds = (minutes - Math.floor(minutes)) * 60;

		return [Math.floor(dCoordinate), Math.floor(minutes), Math.floor(secounds)];
	}

	function _vShowDragRectPrompt() {
		var div = $(DRAG_RECT_PROMPT_DIV_NAME);

		if (null == div) {
			div = document.createElement("div");
			div.id = DRAG_RECT_PROMPT_DIV_NAME;
			div.style.position = "absolute";
			div.style.display = "none";
			div.style.overflow = "hidden";
			div.style.zIndex = 102;
			div.style.left = "0px";
			div.style.top = "0px";
			div.style.width = "90px";
			div.style.height = "36px";
			div.style.fontSize = "12px";
			div.style.color = "#ff0000";

			var text = document.createTextNode("拖曳鼠标拉框或直接单击地图");
			div.appendChild(text);

			oMapInstance.getContainer().appendChild(div);
		}
		
		if (!isNaN(_iCurEventX) && !isNaN(_iCurEventY)){
			div.style.display = "block";
			div.style.left = eval(_iCurEventX + 14) + "px";
			div.style.top = eval(_iCurEventY + 14) + "px";
		}
	}

	function _vHideDragRectPrompt() {
		var div = $(DRAG_RECT_PROMPT_DIV_NAME);
		if (div) {
			div.style.display = "none";
		}
	}
	
	function _vCreateMagnifierMap () {	//初始化“放大镜”地图
		_vHideControls();

		if (_oMagnifierMap) {
			return;
		}

		var mgnfDiv = $("magnifier");
		_oMagnifierMap = new GMap2(mgnfDiv);
		_oMagnifierMap.getMapTypes().length = 0;
		_oMagnifierMap.addMapType(type);
		_oMagnifierMap.setCenter(oMapInstance.getCenter(), oMapInstance.getZoom() + MAGNIFIER_ZOOM_DELTA);
		mgnfDiv.style.display = "none";
		GEvent.addDomListener(mgnfDiv, "mousemove", _vMgnfMouseMove);
		if (mgnfDiv.childNodes.length >= 2) {
			mgnfDiv.childNodes[1].style.display = "none";
		}

		_oMagnifierBorder = $("border");  
		if (_oMagnifierBorder) {
			GEvent.addDomListener(_oMagnifierBorder, "mousemove", _vMgnfMouseMove);
			mgnfDiv.offsetX = mgnfDiv.offsetY = -75;

			var borderImage = _mStaticPath + "glass.png";
			if (3 < IE_VERSION && 7 > IE_VERSION) {
				_oMagnifierBorder.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\"" + borderImage + "\", sizingMethod=\"scale\")";
			}
			else {
				_oMagnifierBorder.style.backgroundImage = "url(" + borderImage + ")";
			}
		}
	}

	function _iGetClickBotton(evt){
		var btn = 0;

		if (null == evt){
			evt = window.event;
		}

		if (Prototype.Browser.IE) {
			btn = evt.button;
		}
		else {
			btn = evt.button;
			switch(btn) {
				case 0:
					btn = 1;
					break;
				case 1:
					btn = 4;
					break;
			}
		}

		return btn;
	}

	function _vHideMagnifierMap() {
		if (_oMagnifierMap) {
			_oMagnifierMap.visible = false;
			_oMagnifierMap.getContainer().style.display = "none";

			if (_oMagnifierBorder)
				_oMagnifierBorder.style.display = "none";
			}
	}

	/**
	* 鼠标移入地图时，显示放大镜
	*/
	function _vMgnfMouseIn() {
		_oMagnifierMap.visible = true;
		_oMagnifierMap.getContainer().style.display = "block";

		if (_oMagnifierBorder) {
			_oMagnifierBorder.style.display = "block";
		}
	}
  
	/**
	* 鼠标在地图上移动时，将“放大镜”放到鼠标所在的位置
	*/
	function _vMgnfMouseMove(e) {
		var x, y;
		e = e || window.event;

		//鼠标移入地图时，显示放大镜
		if (!_oMagnifierMap.visible) {
			_vMgnfMouseIn();
		}

		//获得鼠标相对于页面顶端的坐标
		var posn = _oGetEventPosn(e);
		x = posn.x;
		y = posn.y;

		//获得鼠标相对于地图的坐标
		var mapDiv = oMapInstance.getContainer();
		var posn = _oGetElementPosition(mapDiv);
		var point = new GPoint(x - mapDiv.offsetLeft - 35, y - mapDiv.offsetTop - 35);

		var w = Math.floor(_oMagnifierBorder.offsetWidth/2) - 50;
		var h = Math.floor(_oMagnifierBorder.offsetHeight/2) - 50;
		var x1 = posn.pixelLeft + w;
		var y1 = posn.pixelTop + h
		var x2 = posn.pixelLeft + mapDiv.offsetWidth - w;
		var y2 = posn.pixelTop + mapDiv.offsetHeight - h;
		//鼠标移出地图时，隐藏放大镜
		if (x < x1 || y < y1 || x > x2 || y > y2) {
			_vHideMagnifierMap();
			return;
		}

		//将放大镜中的地图平移到正确的位置
		var latlng = oMapInstance.fromContainerPixelToLatLng(point);
		if (Prototype.Browser.IE && IE_VERSION < 7) {
			_oMagnifierMap.setCenter(latlng);
		}
		else {
			_oMagnifierMap.panTo(latlng);
		}

		//让“放大镜”跟随鼠标移动
		var mgnfDiv = _oMagnifierMap.getContainer();
		mgnfDiv.style.left = x + mgnfDiv.offsetX + "px";
		mgnfDiv.style.top = y + mgnfDiv.offsetY + "px";

		if (_oMagnifierBorder) {
			_oMagnifierBorder.style.left = x + mgnfDiv.offsetX - 31 + "px";
			_oMagnifierBorder.style.top = y + mgnfDiv.offsetY - 31 + "px";
		}
	}
	
	//* 与折线编码相关的函数开始
	function encodeSignedNumber(num) {
		var sgn_num = num << 1;

		if (num < 0) {
			sgn_num = ~(sgn_num);
		}

		return(encodeNumber(sgn_num));
	}

	function encodeNumber(num) {
		var encodeString = "";

		while (num >= 0x20) {
			encodeString += (String.fromCharCode((0x20 | (num & 0x1f)) + 63));
			num >>= 5;
		}

		encodeString += (String.fromCharCode(num + 63));
		return encodeString;
	}

	function createPoint(points, lat, lng, pLevel) {
		var newPoint = {
			Latitude: lat,
			Longitude: lng,
			Level: pLevel
		};

		points.push(newPoint);
	}

	function createEncodings(map, points, color, weight, opacity) {
		var i = 0;

		var plat = 0;
		var plng = 0;

		var encoded_points = "";
		var encoded_levels = "";

		for(i = 0; i < points.length; ++i) {
			var point = points[i];
			var lat = point.Latitude;
			var lng = point.Longitude;
			var level = point.Level;

			var late5 = Math.floor(lat * 1e5);
			var lnge5 = Math.floor(lng * 1e5);

			dlat = late5 - plat;
			dlng = lnge5 - plng;

			plat = late5;
			plng = lnge5;

			encoded_points += encodeSignedNumber(dlat) + encodeSignedNumber(dlng);
			encoded_levels += encodeNumber(level);
		}
		
		if (points.length > 1) {
			document.overlay = GPolyline.fromEncoded({color: color, weight: 5, opacity : 0.95, points: encoded_points, zoomFactor: 32, levels: encoded_levels, numLevels: 4});
			map.addOverlay(document.overlay);
		}
	}
	//* 与折线编码相关的函数结束
	//**“私有方法”结束
	
	//**主函数开始
	for (var i=0; i<aMapControls.length; i++) {
		 if ("object" == typeof(aMapControls[i])) {
			oMapInstance.addControl(aMapControls[i]);
		 }

		 oMapInstance.getContainer().style.backgroundImage = "url(" + _mStaticPath + "ew_map_bg.gif)";
	}
	
	function vShowMapBorder(map, show) {
		var div = map.getContainer().firstChild.firstChild;
		var len = div.childNodes.length;
		for(var i=1; i<2; i++) {
			for(var j=0; j<div.childNodes[i].childNodes.length; j++) {
				for (var k=0; k<div.childNodes[i].childNodes[j].childNodes.length; k++)
				{
					div.childNodes[i].childNodes[j].childNodes[k].style.border = (show) ? "1px solid #000000" : "0px";
				}
			}
		}
	}

	/*GEvent.addListener(oMapInstance, "mouseover", function() {
		vShowMapBorder(oMapInstance, true);
	});
	
	GEvent.addListener(oMapInstance, "mouseout", function() {
		vShowMapBorder(oMapInstance, false);
	});*/

	GEvent.addListener(oMapInstance, "click", function(marker, point) {
		switch(_eCurGisTool) {
			case GIS_TOOL_PAN:		//当使用漫游工具时单击放大
				if (!marker && _bIsLeftInRightOutEnabled) {
					var level = oMapInstance.getZoom() + 1;
					if (level >= MIN_ZOOM_LEVEL && level <= MAX_ZOOM_LEVEL) {
						oMapInstance.setCenter((IE_VERSION > 7) ? _oMouseLatLng : point, level);
					}
				}
				break;
			case GIS_TOOL_LABEL:
				if (!marker) {
					oMapInstance.clearOverlays();
					var icon = new EwMapIcon();
					icon.image = _mStaticPath + "markerYellow.png";
					var newmarker = new GMarker((IE_VERSION > 7) ? _oMouseLatLng : point, {icon : icon, draggable: true, clickable : true, title : "当前标注点"});
					oMapInstance.addOverlay(newmarker);
				}
				break;
			default:
				break;
		}
	});

	GEvent.addListener(oMapInstance, "singlerightclick", function(point, src, marker) {
		switch (_eCurGisTool) {
			case GIS_TOOL_PAN: 	//当使用漫游工具时右击缩小
				if (_bIsLeftInRightOutEnabled) {
					var level = oMapInstance.getZoom() - 1;
					var latlng = oMapInstance.fromDivPixelToLatLng(point);

					if (level >= MIN_ZOOM_LEVEL && level <= MAX_ZOOM_LEVEL) {
						oMapInstance.setCenter((null == _oMouseLatLng) ? latlng : _oMouseLatLng, level);
					}
				}
				break;
			case GIS_TOOL_MEAS_DISTANCE: //当使用测距工具时右击完成测距
				if (null != _oRulerControl) {
					var len = _oRulerControl.getDistance();
					window.alert(_oRulerControl.formatDistance(len));
					_oRulerControl.reset();
				}
			case GIS_TOOL_MEAS_SQUARE: //当使用面积量算时右击完成面积量算
				break;
			default: //返回漫游状态
				eval(sInstanceName).setGisTool(GIS_TOOL_PAN);
				break;
		}
	});

	GEvent.addDomListener(oMapInstance.getContainer(), "mousedown", function(evt) {
		if (null == evt){
			evt = window.event;
		}

		var src = (evt.srcElement) ? evt.srcElement : evt.target;
		var btn = _iGetClickBotton(evt);

		if (1 == btn) {
			switch(_eCurGisTool) {
				case GIS_TOOL_RECT_ZOOM_IN:
				case GIS_TOOL_RECT_ZOOM_OUT:
				case GIS_TOOL_RECT_SELECT:
					_oMapCoverDiv.onselectstart = function() { return false; };
					if (_oMapCoverDiv.firstChild.setCapture) {
						_oMapCoverDiv.firstChild.setCapture(false);
					}
					//else if(window.captureEvents) {
					//	window.captureEvents(Event.MOUSEDOWN);
					//}
					var posn1 = _oGetElementPosition(oMapInstance.getContainer());
					var posn2 = _oGetEventPosn(evt);
					_iOriEventX = posn2.x - posn1.pixelLeft;
					_iOriEventY = posn2.y - posn1.pixelTop;
					_vDisplayDragRect(_oMapCoverDiv);

					_iCurEventX = _iOriEventX;
					_iCurEventY = _iOriEventY;
					_vResizeDragRect(_oMapCoverDiv, _iOriEventX, _iOriEventY, _iCurEventX, _iCurEventY);
					_vHideDragRectPrompt();
					break;
				default:
					break;
			}
		}
	});

	GEvent.addDomListener(oMapInstance.getContainer(), "mouseup", function(evt) {
	    if (null == evt) {
	        evt = window.event;
	    }

	    var src = (evt.srcElement) ? evt.srcElement : evt.target;
	    var btn = _iGetClickBotton(evt);

	    if (1 == btn) {
	        if (_oMapCoverDiv) {
	            _vHiddenDragRect(_oMapCoverDiv);
	            _oMapCoverDiv.onselectstart = function() { return true; };
	            if (_oMapCoverDiv.firstChild.releaseCapture) {
	                _oMapCoverDiv.firstChild.releaseCapture();
	            }
	            //else if(window.captureEvents) {
	            //	window.captureEvents(Event.MOUSEDOWN);
	            //}
	        }

	        var width = Math.abs(_iCurEventX - _iOriEventX);
	        var height = Math.abs(_iCurEventY - _iOriEventY);
	        var center;
	        var level;

	        switch (_eCurGisTool) {
	            case GIS_TOOL_RECT_ZOOM_IN:
	                if (width < 4 || height < 4) {
	                    center = _oMouseLatLng;
	                    level = oMapInstance.getZoom() + 1;
	                    level = (level >= MAX_ZOOM_LEVEL) ? MAX_ZOOM_LEVEL : level;
	                }
	                else {
	                    var nw = oMapInstance.fromContainerPixelToLatLng(new GPoint(_iOriEventX, _iOriEventY));
	                    var ne = oMapInstance.fromContainerPixelToLatLng(new GPoint(_iCurEventX, _iOriEventY));
	                    var se = oMapInstance.fromContainerPixelToLatLng(new GPoint(_iCurEventX, _iCurEventY));
	                    var sw = oMapInstance.fromContainerPixelToLatLng(new GPoint(_iOriEventX, _iCurEventY));
	                    var zoomAreaPoly = new GPolyline([nw, ne, se, sw, nw]);
	                    var polyBounds = zoomAreaPoly.getBounds();
	                    center = polyBounds.getCenter();
	                    level = oMapInstance.getBoundsZoomLevel(polyBounds);
	                }
	                oMapInstance.setCenter(center, level);
	                break;
	            case GIS_TOOL_RECT_ZOOM_OUT:
	                if (width < 4 || height < 4) {
	                    center = oMapInstance.fromContainerPixelToLatLng(new GPoint(_iOriEventX, _iOriEventY));
	                    level = oMapInstance.getZoom() - 1;
	                    level = (level <= MIN_ZOOM_LEVEL) ? MIN_ZOOM_LEVEL : level;
	                }
	                else {
	                    var size = oMapInstance.getSize();
	                    var ratex = size.width / width;
	                    var ratey = size.height / height;
	                    var rate = (ratex > ratey) ? ratey : ratex;
	                    level = oMapInstance.getZoom() - Math.floor(rate);
	                    level = (level <= MIN_ZOOM_LEVEL) ? MIN_ZOOM_LEVEL : level;
	                    center = new GPoint(_iOriEventX + Math.floor(width / 2), _iOriEventY + Math.floor(height / 2));
	                    center = oMapInstance.fromContainerPixelToLatLng(center);
	                }
	                oMapInstance.setCenter(center, level);
	                break;
	            case GIS_TOOL_RECT_SELECT:
	                //外部函数，用于选择后处理，需要自行添加
	                rectSelect(_iOriEventX, _iOriEventY, _iCurEventX, _iCurEventY);
	                break;
	            default:
	                break;
	        }

	        _iOriEventX = 0;
	        _iOriEventY = 0;
	        _iCurEventX = 0;
	        _iCurEventY = 0;
	    }
	});

	GEvent.addDomListener(oMapInstance.getContainer(), "mousemove", function(evt) {
		var posn1 = _oGetElementPosition(oMapInstance.getContainer());
		var posn2 = _oGetEventPosn(evt);
		_iCurEventX = posn2.x - posn1.pixelLeft;
		_iCurEventY = posn2.y - posn1.pixelTop;

		switch(_eCurGisTool) {
			case GIS_TOOL_RECT_ZOOM_IN:
			case GIS_TOOL_RECT_ZOOM_OUT:
			case GIS_TOOL_RECT_SELECT:
				if (0 == _iOriEventX && 0 == _iOriEventY) {
					_vShowDragRectPrompt();
				}
				else {
					_vResizeDragRect(_oMapCoverDiv, _iOriEventX, _iOriEventY, _iCurEventX, _iCurEventY);
				}
				break;
			case GIS_TOOL_MAGNIFIER:
				_vMgnfMouseMove(evt);
			default:
				break;
		}
	});

	GEvent.addListener(oMapInstance, "mousemove", function(latlng) {
		_oMouseLatLng = latlng;

		if (_bIsShowCoordInStatus) {
			var coordinateX = _aGetMinAndSec(latlng.lng());
			var coordinateY = _aGetMinAndSec(latlng.lat());
			window.status = latlng.lng() + ((latlng.lng()>0) ? "(东经" : "(西经") + coordinateX[0] + "°" + coordinateX[1] + "′" + coordinateX[2] + "″) " + latlng.lat() + ((latlng.lng()>0) ? "(北纬" : "(南纬") + coordinateY[0] + "°" + coordinateY[1] + "′" + coordinateY[2] + "″)";
		}
	});

	GEvent.addListener(oMapInstance, "mouseout", function(latlng) {
		_oMouseLatLng = latlng;

		if (IE_VERSION > 3) {	 //IE
			var tag = event.srcElement;
			if (tag != null && ($(DRAG_RECT_DIV_NAME) == tag || $(DRAG_RECT_PROMPT_DIV_NAME) == tag)) {
				return;
			}
		}

		_vHiddenDragRect(_oMapCoverDiv);
		_vHideDragRectPrompt();
		
		//oMapInstance.closeInfoWindow();	//鼠标离开地图时关闭信息窗

		_iOriEventX = 0;
		_iOriEventY = 0;
		_iCurEventX = 0;
		_iCurEventY = 0;
	});

	GEvent.addListener(oMapInstance, "zoomend", function(oldlevel, newlevel) {
		if (_oMagnifierMap) {
			_oMagnifierMap.setZoom(newlevel + MAGNIFIER_ZOOM_DELTA);
		}
	});
	//**主函数结束
}

function EwMapIcon (){
	this.shadow = _mStaticPath + "shadow50.png";
	this.image = _mStaticPath + "marker.png";
	this.iconSize = new GSize(20, 34);
	this.shadowSize = new GSize(37, 34);
	this.iconAnchor = new GPoint(9, 34);
	this.infoWindowAnchor = new GPoint(9, 2);
	this.infoShadowAnchor = new GPoint(18, 25);
}
EwMapIcon.prototype = new GIcon();

function EwMapHistory () {
	var array = [];
	var index = 0;

	this.add = function (center, level) {
		//TODO:需要判断是否已经在操作历史中切换，如果是，需要重写当前步骤以后的操作历史
		array[index++] = new EwMapHistoryInfo(center, level);
		//TODO:激发回退按钮可用事件
	}

	this.back = function (map) {
		var i = --index;
		if (i >= 0 && i < array.length) {
			var info = array[i];
			map.setCenter(info.center, info.level);
			//TODO:激发前进按钮可用事件
		}
		else {
			index = 0;
			//TODO:激发后退按钮不可用事件
		}
	}

	this.forword = function (map) {
		var i = ++index;
		if (i >= 0 && i < array.length) {
			var info = array[i];
			map.setCenter(info.center, info.level);
		}
		else {
			index = array.length - 1;
			//TODO:激发前进按钮不可用事件
		}
	}
}

function EwMapHistoryInfo (center, level){
	this.center = center;
	this.level = level;
}

function GReturnToPanControl() {
	this.BACKGROUND_IMAGE_ = _mStaticPath + "ruler_background.png";
}

GReturnToPanControl.prototype = new GControl();

GReturnToPanControl.prototype.initialize = function(map) {
	var container = document.createElement("div");
	container.style.backgroundImage = "url(" + this.BACKGROUND_IMAGE_ + ")";
	container.style.fontSize = "12px";
	container.style.color = "#ff0000";
	container.style.border = "1px solid #888888";
	container.style.padding = "4px";
	container.style.textAlign = "left";
	
	var node = document.createTextNode("地图覆盖物等控件不可用，按鼠标右键返回漫游状态。");
	container.appendChild(node);
	
	map.getContainer().appendChild(container);
	
	return container;
}

GReturnToPanControl.prototype.getDefaultPosition = function() {
	return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(8, 8));
}

