//=====================================================//
// VMDefine
//=====================================================//
var VMDefine = {
	TILE_WIDTH 	 : 640,		//タイルのサイズ
	TILE_HEIGHT  : 528,		//タイルのサイズ
	TILE_ROWS    : 29,		//タイルの数（奇数）
	TILE_COLUMNS: 29,		//タイルの数（奇数）
	DEFAULT_ZOOM : 1,		//縮尺初期値
	DEFAULT_ICON : "ico_default.png",

//	ImgDir : "/jafnavi/map/images/",
//	MAPPROC 	 : "/jafnavi/map/mapimg.php",
//	POINTPROC    : "/jafnavi/map/getMapPoint.php"

	MAPPROC 	 : "/map/mapimg.php",//本番
	ImgDir : "/map/images/",//本番
	POINTPROC    : "/map/getMapPoint.php"//本番

}
//=====================================================//
// VMPeriodicalExecuterクラス
//=====================================================//
var VMPeriodicalExecuter = Class.create();
VMPeriodicalExecuter.prototype = {
	//=====================================================//
	// コンストラクタ
	// 引数： map - VMapインスタンス
	//		aLatLng - VMLatLngの配列
	//      speed - 実行スピード（秒）
	// 戻り値：VMapインスタンス
	// 機能：初期化
	//=====================================================//
	initialize : function(map,aLatLng,speed) { 
		this.map = map;
		this.typename = "VMPeriodicalExecuter";
		this.aLatLng = aLatLng;
		this.timer = null;//タイマーオブジェクト
		this.bInit = false;//true:初期化済み
		if(speed){
			this.speed = speed;
		}else{
			this.speed = 1;//秒
		}
		if(this.map.onSimulating){
			return;
		}else{
			this.map.setCenter(this.aLatLng[0]);
		    //アイコン再描画
		    this.map.addIcons(this.map.aIcons);
			this.frameCount = 1;
			this.bInit = true;
		}
	},
	//=====================================================//
	// メソッド:start
	// 引数： なし
	// 戻り値：なし
	// 機能：スタート／リスタート
	//=====================================================//
	start : function(){
		if(this.map.onSimulating){
			alert("実行中です");
			return;
		}
		if(this.map.nScaleLevel >= 1 && this.map.nScaleLevel <= 3){
			alert("現在の縮尺では実行できません");
			return;
		}
		if(!this.bInit){
			this.map.setCenter(this.aLatLng[0]);
		    //アイコン再描画
		    this.map.addIcons(this.map.aIcons);
			this.frameCount = 1;
			this.bInit = true;			
		}
		//prototype.jsのクラスを使用
		this.timer = new PeriodicalExecuter(this.exec.bindAsEventListener(this), this.speed);
		this.map.onSimulating = true;
		this.map.disableDragging();
		this.map.disableDoubleClickCenter();
	},
	exec : function(){
		//スクロール
		this.map.scrollTo(this.aLatLng[this.frameCount]);
		//地図差分ロード
	    this.map.loadImage(this.map.oImgBufPos.x, this.map.oImgBufPos.y);
		if(this.map.endCheck()==false){	//divの終端に達した場合
			//現在の中心点緯度経度計算（スクロール移動量計算）　
			if(this.map.calcCenter()==false){
				alert("地図表示の有効範囲外です");
				return
			}
			//画像格納領域を削除、再作成
			this.map.createElemImgBuf();
			//地図ロード
		    this.map.loadImage(this.map.oImgBufPos.x, this.map.oImgBufPos.y);
			//左上・右下緯度経度を取得、1ピクセルあたりの緯度経度を計算して保持
			this.map.calcPerPix();
		    //アイコン再描画
		    this.map.addIcons(this.map.aIcons);
		}
		this.frameCount++;
		if(this.aLatLng.length==this.frameCount){
			this.stop();
			this.endfunc();
		}
	},
	//=====================================================//
	// メソッド:endfunc
	// 引数： なし
	// 戻り値：なし
	// 機能：終了時のコールバック関数。ユーザーがオーバーライドして使用
	//=====================================================//
	endfunc : function(){},
	//=====================================================//
	// メソッド:stop
	// 引数： なし
	// 戻り値：なし
	// 機能：タイマーをキャンセルし、callback 関数が呼び出されないようにする。
	//=====================================================//
	stop : function(){
		this.timer.stop();
		//開始フレームを初期化
		this.frameCount=0;
		this.map.onSimulating = false;
		this.map.enableDragging();
		this.map.enableDoubleClickCenter();
	},
	//=====================================================//
	// メソッド:pause
	// 引数： なし
	// 戻り値：　なし
	// 機能：　一時停止
	//=====================================================//
	pause : function(){
		this.timer.stop();
		this.map.onSimulating = false;
		this.map.enableDragging();
		this.map.enableDoubleClickCenter();
	}
}
//=====================================================//
// VMapクラス
//=====================================================//
var VMap = Class.create();
VMap.prototype = {
	//=====================================================//
	// コンストラクタ
	// 引数：container - 表示領域divの参照
	//	   simple_mode - trueの場合タイルを１×１とする。
	// 戻り値：VMapインスタンス
	// 機能：初期化
	//=====================================================//
	initialize : function(container,simple_mode) { 
		this.typename = "VMap";
		VMInstances.setInstance(this);

		/********************************************/
	    // コンテナ（地図＋コントロール）
		/********************************************/
		this.container = container;
		if(this.container.style.width==""){
		    this.container.style.width = "525px";
		}
		if(this.container.style.height==""){
		    this.container.style.height = "400px";
		}
	    this.container.style.position = "relative";
	    this.container.style.overflow = "hidden";
		this.container.style.background = "#CCCCCC";
		VMCommon.setUnselectable(this.container);
		
	    //地図表示領域作成
	    this.elemOut = document.createElement("div");
		this.elemOut.id = this.container.id + "_out";
	    this.elemOut.style.width = this.container.style.width;
	    this.elemOut.style.height = this.container.style.height;
	    this.elemOut.style.position = "relative";
	    this.elemOut.style.overflow = "hidden";
		this.elemOut.style.top = "0px";
		this.elemOut.style.left = "0px";
		this.elemOut.style.margin = "0px";
		this.elemOut.style.padding = "0px";
		this.elemOut.style.border = "0px";
	    this.elemOut.style.cursor = "move";
	    this.container.appendChild(this.elemOut);
		this.oOutParentOffset = new VMPoint(0,0);//コンテナとのオフセット
		this.oOutSize = new VMSize(VMCommon.getNumber(this.elemOut.style.width),VMCommon.getNumber(this.elemOut.style.height));

		/********************************************/
		// 画像格納領域
		/********************************************/
		//タイルのオフセット（CGIパラメータ：OFF_X,OFF_Y）
 		this.sfs_x = new Object();
		this.sfs_y = new Object();
		
		//2008/5/23 add start
		if(simple_mode){
			this.TILE_WIDTH = this.oOutSize.width;
			this.TILE_HEIGHT = this.oOutSize.height;
			this.TILE_ROWS    = 1;
			this.TILE_COLUMNS = 1;
		}else{
			this.TILE_WIDTH = VMDefine.TILE_WIDTH;
			this.TILE_HEIGHT = VMDefine.TILE_HEIGHT;
			this.TILE_ROWS    = VMDefine.TILE_ROWS;
			this.TILE_COLUMNS = VMDefine.TILE_COLUMNS;
		}		
		//タイルのサイズと数
		this.oTileSize =  new VMSize(this.TILE_WIDTH,this.TILE_HEIGHT);//w,h
		this.nTileRows    = this.TILE_ROWS;
		this.nTileColumns = this.TILE_COLUMNS;
		//2008/5/23 add end


		//新規element作成
		this.elemImgBuf;
		this.createElemImgBuf();
		/********************************************/
		//緯度経度
		/********************************************/
		this.oCenterLatLng;			//VMLatLng型
		this.oCenterLatLng_buf;     //VMLatLng型　縮尺１，２記憶用
		this.oLeftTopLatLng;		//VMLatLng型
		this.oRightBottomLatLng;	//VMLatLng型
		this.lat_per_pix;			//1ピクセルの重さ。1000ミリ秒
		this.lng_per_pix;		
//		this.dist;
//		this.per_meter;
		
		/********************************************/
		// コントロール関連
		/********************************************/		
		//ロード済みフラグ
		this.bLoaded = false;	
		//縮尺レベル - デフォルト
		this.nScaleLevel = VMDefine.DEFAULT_ZOOM;
		//ウィンドウ座標
		this.nTop_dif;           // マウスポインタと画像のY座標の差分
		this.nLeft_dif;          // マスポインタと画像のX座標の差分
		this.oOutPos;			//VMPoint
		//コントロール管理（リサイズ等）
		this.nControlSerial = 0;
		this.aControls = new Array();
		this.scaleButtonsInst = null;

		/********************************************/
		// CGI関連
		/********************************************/
		//地図リクエストパラメータ
		this.oReqParams = new VMParams();

		/********************************************/
		// イベント設定
		/********************************************/
		//イベント設定（デフォルト）
		this.bDragging = true;          //マウスドラッグ
//		this.enableDragging();
		VMEvent.addDraggingListener(this);
		this.bDoubleClickCenter = true; //ダブルクリック中心移動
//		this.enableDoubleClickCenter();
		VMEvent.addDblClickListener(this);
		
		//アイコン管理（一括削除等）
		this.nIconSerial = 0;
		this.aIcons = new Array();

		/********************************************/
		// クレジット表示
		/********************************************/
		this.createCredit();

		/********************************************/
		// 中心クロスマーク表示
		/********************************************/
		this.bCrossMark = true;
		this.createCrossMark();
		
		/********************************************/
		// ルートシュミレーション実行中フラグ
		/********************************************/
		this.onSimulating = false;

	},
	//=====================================================//
	// メソッド名：getReqParams
	// 引数： なし
	// 戻り値： VMParams - パラメータのオブジェクト
	// 機能：　現在のパラメータ設定を取得する
	//=====================================================//
	getReqParams : function(){
		return this.oReqParams;
	},
	//=====================================================//
	// メソッド名：setReqParams
	// 引数： oReqParams - VMParamsインスタンス
	// 戻り値： なし
	// 機能：　パラメータ設定を更新する
	//=====================================================//
	setReqParams : function(oReqParams){
		this.oReqParams = oReqParams;
	},
	//=====================================================//
	// メソッド名（非公開）：setTileSettei
	// 引数：zoom - 縮尺レベル
	// 戻り値：なし
	// 機能：　タイルの数・サイズ・オフセットを設定 スケール変更のつど実行
	//=====================================================//
	setTileSettei : function(zoom){
		//縮尺レベルによってタイル数／サイズを再設定
		if(zoom >= 4){
			this.nTileRows    = this.TILE_ROWS;
			this.nTileColumns = this.TILE_COLUMNS;
			this.oTileSize = new VMSize(this.TILE_WIDTH,this.TILE_HEIGHT);
			this.container.style.background = "#CCCCCC";
		}else if(zoom == 3){
			//固定の中心座標で1枚地図を取得
			//中心座標保存しておく。ロード後に自動スクロールさせる
			this.oCenterLatLng_buf = new VMLatLng(this.oCenterLatLng.lat,this.oCenterLatLng.lng);
			var lat = "N36.00.00.000";
			var lng = "E136.26.15.792";
			this.oCenterLatLng = new VMLatLng(lat,lng);
			this.nTileRows    = 3;
			this.nTileColumns = 3;
			this.oTileSize = new VMSize(700,800);//これ以上大きくすると白い枠が出てしまうので固定
			this.container.style.background = "#66FFFF";
		}else if(zoom == 2){
			//固定の中心座標で1枚地図を取得
			//中心座標保存しておく。ロード後に自動スクロールさせる
			this.oCenterLatLng_buf = new VMLatLng(this.oCenterLatLng.lat,this.oCenterLatLng.lng);
			var lat = "N36.00.00.000";
			var lng = "E136.26.15.792";
			this.oCenterLatLng = new VMLatLng(lat,lng);
			this.nTileRows    = 1;
			this.nTileColumns = 1;
			this.oTileSize = new VMSize(1000,1200);//これ以上大きくすると白い枠が出てしまうので固定
			this.container.style.background = "#66FFFF";
		}else if(zoom == 1){
			//固定の中心座標で1枚地図を取得
			//中心座標保存しておく。ロード後に自動スクロールさせる
			this.oCenterLatLng_buf = new VMLatLng(this.oCenterLatLng.lat,this.oCenterLatLng.lng);
			var lat = "N36.00.00.000";
			var lng = "E136.26.15.792";
			this.oCenterLatLng = new VMLatLng(lat,lng);
			this.nTileRows    = 1;
			this.nTileColumns = 1;
			this.oTileSize = new VMSize(600,560);//これ以上大きくすると白い枠が出てしまうので固定
			this.container.style.background = "#66FFFF";
		}else{
			alert("VMap.setTileSettei 縮尺が設定されていません：" + zoom);
			return;
		}
		//タイルのオフセット設定
		this.setTileOffsetAry(this.nTileRows,this.nTileColumns);
	},
	//=====================================================//
	// メソッド名（非公開）：setTileOffsetAry
	// 引数：row_cnt - タイル行数
	//     col_cnt - タイル列数
	// 戻り値：なし
	// 機能：　this.sfs_x,this.sfs_yを設定
	//=====================================================//
	setTileOffsetAry : function(row_cnt,col_cnt){
		//タイルのオフセット設定
		var n = -Math.floor(col_cnt / 2);
		for(var i = 0;i < col_cnt;i++){
			this.sfs_x[i] = n;
			n++;
		}
		var n = Math.floor(row_cnt / 2);
		for(var i = 0;i < row_cnt;i++){
			this.sfs_y[i] = n;
			n--;
		}		
	},
	//=====================================================//
	// メソッド名（非公開）：setOutSize
	// 引数：oSize - VMSizeオブジェクト
	// 戻り値：なし
	// 機能： 出力領域設定・再設定。矢印コントロールを追加・地図サイズ変わった時実行
	//=====================================================//
	changeOutSize : function(oSize){
		this.oOutSize = oSize;
		//elemOutの子要素の属性を更新
		this.initImgBufOffset();
		this.showCredit();
		if(this.bCrossMark){
			this.showCrossMark();
		}
	},
	//=====================================================//
	// メソッド名（非公開）：createCredit
	// 引数：なし
	// 戻り値：なし
	// 機能： クレジット表示領域作成
	//=====================================================//
	createCredit :function(){
		this.elemCredit = document.createElement("div");
		this.elemCredit.id = this.container.id + "_credit";
		this.elemCredit.style.background = "#FFFFFF";
		this.elemCredit.style.fontSize = "10pt";
		this.elemCredit.style.position = "absolute";
		VMCommon.setUnselectable(this.elemCredit);
		this.elemCredit.innerHTML = "&copy; 住友電工";
		this.elemCredit.style.zIndex = 100;
		this.elemOut.appendChild(this.elemCredit);
		this.showCredit();
	},
	//=====================================================//
	// メソッド名（非公開）：showCredit
	// 引数：なし
	// 戻り値：なし
	// 機能： クレジット表示（位置調整）
	//=====================================================//
	showCredit : function(){
		var y = this.oOutSize.height - 30;
		var x = this.oOutSize.width - 100;
		this.elemCredit.style.top = y + "px";
		this.elemCredit.style.left = x + "px";
	},
	//=====================================================//
	// メソッド名（非公開）：createCrossMark
	// 引数：なし
	// 戻り値：なし
	// 機能：　中心クロスマーク表示
	//=====================================================//
	createCrossMark: function(){
		this.elemCrossMark = document.createElement("div");
		this.elemCrossMark.id = this.container.id + "_cross";
		this.elemCrossMark.style.position = "absolute";
		this.elemCrossMark.style.zIndex = 100;
		this.imgCrossMark = document.createElement("img")
		this.imgCrossMark.src = VMDefine.ImgDir + "cross_mark.gif";
		this.imgCrossMark.width = "30";
		this.imgCrossMark.height = "30";
		this.elemCrossMark.appendChild(this.imgCrossMark);
		this.elemOut.appendChild(this.elemCrossMark);
		this.showCrossMark();
		//マウスオーバーイベント（アイコンプロット不可に設定）
		VMEvent.addEventListener(this.elemCrossMark,"mouseover",VMEvent.disableAddIcon);
		//注）removeされるとmouseoutイベント発生しない。disableのままになってしまう
		VMEvent.addEventListener(this.elemCrossMark,"mouseout",VMEvent.enableAddIcon);
	},
	//=====================================================//
	// メソッド名：showCrossMark
	// 引数：なし
	// 戻り値：なし
	// 機能：　中心クロスマーク表示
	//=====================================================//
	showCrossMark: function(){
		var y = (this.oOutSize.height / 2) - (this.imgCrossMark.height / 2);
		var x = (this.oOutSize.width / 2) - (this.imgCrossMark.width / 2);
		this.elemCrossMark.style.top = y + "px";
		this.elemCrossMark.style.left = x + "px";
		this.elemCrossMark.style.display = "";
		this.bCrossMark = true;
	},
	//=====================================================//
	// メソッド名：hideCrossMark
	// 引数：なし
	// 戻り値：なし
	// 機能： 中心クロスマーク非表示
	//=====================================================//
	hideCrossMark :function(){
		this.elemCrossMark.style.display = "none";
		this.bCrossMark = false;
	},
	//=====================================================//
	// メソッド名（非公開）：initImgBufOffset
	// 引数：なし
	// 戻り値：なし
	// 機能：画像格納領域オフセット初期化
	//=====================================================//
	initImgBufOffset : function(){
		//画像格納領域 - 設定初期化
		var x = -((this.oTileSize.width * this.nTileColumns / 2) - (this.oOutSize.width / 2));
		var y = -((this.oTileSize.height * this.nTileRows / 2) - (this.oOutSize.height / 2));
	    this.oImgBufPos = new VMPoint(x,y);
		this.elemImgBuf.style.left = this.oImgBufPos.x + 'px';
	    this.elemImgBuf.style.top  = this.oImgBufPos.y + 'px';
	    //画像格納領域 - オフセット初期値保存
	    this.oImgBufPosOrg = new VMPoint(this.oImgBufPos.x,this.oImgBufPos.y);
	},
	//=====================================================//
	// メソッド名（非公開）：endCheck
	// 引数：なし
	// 戻り値：Boolean
	// 機能： 画像格納領域div内かどうかチェック true:div内 false:over
	//	（divの終端に達するのは手でスクロールした場合とダブルクリックセンター移動の場合）
	//=====================================================//
	endCheck : function(){
		var bRet = true;
		var oPos1 = VMCommon.getDocumentOffset(this.elemImgBuf);
		var oPos2 = VMCommon.getDocumentOffset(this.elemOut);
		if(oPos1.x >= oPos2.x || oPos1.y >= oPos2.y){
			bRet = false;
			//alert("画像格納領域divの端に達しました（上、左）");
		}
		if((oPos2.x + this.oOutSize.width)>= (oPos1.x + (this.oTileSize.width * this.nTileColumns))){
			bRet = false;
			//alert("画像格納領域divの端に達しました（右）");			
		}
		if((oPos2.y + this.oOutSize.height)>= (oPos1.y + (this.oTileSize.height * this.nTileRows))){
			bRet = false;
			//alert("画像格納領域divの端に達しました（下）");			
		}
		if(!bRet){
			//alert("x  " + oPos1.x + " : " + oPos2.x);
			//alert("y  " + oPos1.y + " : " + oPos2.y);
			//alert("画像格納領域divの端に達しました");
		}
		return bRet;
	},
	//=====================================================//
	// メソッド名（非公開）：isLoaded
	// 引数：なし
	// 戻り値：Boolean
	// 機能：setCenter()で初期化されていたらtrueを返す 
	//=====================================================//
	isLoaded : function(){
		return this.bLoaded;
	},
	//=====================================================//
	// メソッド名：enableDragging
	// 引数：なし
	// 戻り値：なし
	// 機能：ドラッグ可能に設定
	//=====================================================//
	enableDragging : function(){
		//VMEvent.addDraggingListener(this);
	    this.elemOut.style.cursor = "move";
		this.bDragging = true;
	},
	//=====================================================//
	// メソッド名：disableDragging
	// 引数：なし
	// 戻り値：なし
	// 機能：ドラッグ不可に設定
	//=====================================================//
	disableDragging : function(){
//	    this.elemOut.style.cursor = "pointer";
	    this.elemOut.style.cursor = "auto";
		this.bDragging = false;
	},
	//=====================================================//
	// メソッド名：draggingEnabled
	// 引数：なし
	// 戻り値：Boolean
	// 機能：ドラッグ設定取得
	//=====================================================//
	draggingEnabled : function(){
		return this.bDragging;
	},
	//=====================================================//
	// メソッド名：enableDoubleClickCenter
	// 引数：なし
	// 戻り値：なし
	// 機能： ダブルクリック中心点移動可能に設定
	//=====================================================//
	enableDoubleClickCenter : function(){
		if(this.elemOut.style.cursor == "pointer"){
			this.elemOut.style.cursor = "crosshair";
		}
		this.bDoubleClickCenter = true;
	},
	//=====================================================//
	// メソッド名：disableDoubleClickCenter
	// 引数：なし
	// 戻り値：なし
	// 機能：ダブルクリック中心点移動不可に設定 
	//=====================================================//
	disableDoubleClickCenter : function(){
		if(this.elemOut.style.cursor == "crosshair"){
			this.elemOut.style.cursor = "pointer";
		}
		this.bDoubleClickCenter = false;
	},
	//=====================================================//
	// メソッド名：doubleClickCenterEnabled
	// 引数：なし
	// 戻り値：Boolean
	// 機能：ダブルクリック中心点移動設定取得
	//=====================================================//
	doubleClickCenterEnabled : function(){
		return this.bDoubleClickCenter;
	},
	//=====================================================//
	// メソッド名：setCenter
	// 引数：latLng - VMLatLngオブジェクト
	//     Optional zoom - ズームレベル
	// 戻り値：なし
	// 機能：中心座標設定
	//=====================================================//
	setCenter : function(latLng,zoom){
		if(latLng.typename!="VMLatLng"){
			alert("setCenter 引数の型が異なります:" + latLng.typename);
			return;
		}
		//中心点設定
		this.oCenterLatLng = latLng;
		//縮尺設定
		if(zoom){
			this.nScaleLevel = zoom;
			//ボタン選択状態に
			for(var i = 0;i < this.aControls.length;i++){
				if(this.aControls[i].typename == "VMZoomControl"){
					this.aControls[i].setButtons(this);
				}
			}
		}
		this.setTileSettei(this.nScaleLevel);
		//新規element作成
		this.createElemImgBuf();
		//左上・右下緯度経度を取得、1ピクセルあたりの緯度経度を計算して保持
		this.calcPerPix();
		//縮尺１，２の場合ロード後に中心点へ自動スクロールさせる
		// （ロードする前にスクロールすること。スクロール後の表示領域の地図をロードさせるため）
		this.scrollToCenter();
		//画像ロード
		this.loadImage(this.oImgBufPos.x,this.oImgBufPos.y);
	},
	//=====================================================//
	// メソッド名（非公開）：scrollToCenter
	// 引数：なし
	// 戻り値：なし
	// 機能：縮尺１、２、３の場合、ロード後に中心点に自動スクロールさせる
	//     実行する前に、calcPerPixを実行する必要がある
	//=====================================================//
	scrollToCenter : function(){
		if(!this.oCenterLatLng_buf){
			return;
		}
		if(this.nScaleLevel >= 1 && this.nScaleLevel <= 3){
			//this.oCenterLatLng_bufまでスクロールさせる
			var lat_sec_diff = this.oCenterLatLng_buf.lat_sec - this.oCenterLatLng.lat_sec;
			var lng_sec_diff = this.oCenterLatLng_buf.lng_sec - this.oCenterLatLng.lng_sec;
			var x_pix = lng_sec_diff / this.lng_per_pix;
			var y_pix = -(lat_sec_diff / this.lat_per_pix);
			this.oImgBufPos.x = this.oImgBufPos.x - x_pix;
			this.oImgBufPos.y = this.oImgBufPos.y - y_pix;
			this.elemImgBuf.style.left = Math.round(this.oImgBufPos.x) + 'px';
			this.elemImgBuf.style.top = Math.round(this.oImgBufPos.y) + 'px';
			this.oCenterLatLng_buf = null;
		}
	},
	scrollTo : function(LatLng){
		var oCenter = this.getCenter();
		var lat_sec_diff = LatLng.lat_sec - oCenter.lat_sec;
		var lng_sec_diff = LatLng.lng_sec - oCenter.lng_sec;
		var x_pix = lng_sec_diff / this.lng_per_pix;
		var y_pix = -(lat_sec_diff / this.lat_per_pix);
		this.oImgBufPos.x = this.oImgBufPos.x - x_pix;
		this.oImgBufPos.y = this.oImgBufPos.y - y_pix;
		this.elemImgBuf.style.left = Math.round(this.oImgBufPos.x) + 'px';
		this.elemImgBuf.style.top = Math.round(this.oImgBufPos.y) + 'px';
	},
	//=====================================================//
	// メソッド名：getCenter
	// 引数：なし
	// 戻り値：latLng - VMLatLngオブジェクト
	// 機能：中心座標取得
	//=====================================================//
	getCenter : function(){
		//地図スクロールの移動量を求める
		var offset_y = this.oImgBufPosOrg.y - this.oImgBufPos.y;
		var offset_x = this.oImgBufPosOrg.x - this.oImgBufPos.x;
		if(offset_x==0&&offset_y==0){
			return this.oCenterLatLng;
		}
		var lat_sec = this.oCenterLatLng.lat_sec;
		var lng_sec = this.oCenterLatLng.lng_sec;
		//オフセット値を加減
		lat_sec = lat_sec - (this.lat_per_pix * offset_y);
		lng_sec = lng_sec + (this.lng_per_pix * offset_x);
		//有効範囲チェック
		if(this.validArea(lat_sec,lng_sec)==false){
			//範囲外のため更新せず終了
			//スクロール移動前の値を返す。VMLatLngオブジェクトを返さないと
			// 実装済みのユーザープログラムでエラーになるため。
			return this.oCenterLatLng;
		}
		//中心座標更取得
		var oRet = new VMLatLng(lat_sec,lng_sec);
		return oRet;
	},
	//=====================================================//
	// メソッド名：getLeftTopLatLng
	// 引数：なし
	// 戻り値：latLng - VMLatLngオブジェクト
	// 機能：左上座標更新・取得
	//=====================================================//
	getLeftTopLatLng : function(){
		if(this.nScaleLevel>=1 && this.nScaleLevel<=3){
			//地図スクロールの移動量を求める
			var offset_y = this.oImgBufPosOrg.y - this.oImgBufPos.y;
			var offset_x = this.oImgBufPosOrg.x - this.oImgBufPos.x;
			if(offset_x==0&&offset_y==0){
				return this.oLeftTopLatLng;
			}
			var lat_sec = this.oCenterLatLng.lat_sec;
			var lng_sec = this.oCenterLatLng.lng_sec;
			//オフセット値を加減
			lat_sec = lat_sec - (this.lat_per_pix * offset_y);
			lng_sec = lng_sec + (this.lng_per_pix * offset_x);
			//左上座標取得
			lat_sec = lat_sec + (this.lat_per_pix * this.oOutSize.height / 2);
			lng_sec = lng_sec - (this.lng_per_pix * this.oOutSize.width / 2);

		}else{
			//2008/5/27 start
//			var lat_sec = this.oCenterLatLng.lat_sec;
//			var lng_sec = this.oCenterLatLng.lng_sec;
			var oCenter = this.getCenter();
			var lat_sec = oCenter.lat_sec;
			var lng_sec = oCenter.lng_sec;
			//2008/5/27 end
			lat_sec = lat_sec + (this.lat_per_pix * this.oOutSize.height / 2);
			lng_sec = lng_sec - (this.lng_per_pix * this.oOutSize.width / 2);
		}
		return new VMLatLng(lat_sec,lng_sec);
	},
	//=====================================================//
	// メソッド名（非公開）：calcCenter
	// 引数：なし
	// 戻り値：boolean - true:成功 false:失敗（範囲外のため計算できない）
	// 機能：スクロールの移動量から中心点、左上座標を更新する
	//=====================================================//
	calcCenter : function(){
		/*--------------------------------------------------*/
		// （注意）		
		// このメソッドを実行すると、this.oCenterLatLng / this.oLeftTopLatLng が更新されます！
		// 更新して良いケース・・・
		//  1)setZoom時
		//  2)setMapMovingで終端に達した場合
		//　いずれもdivを再構築し新規に地図をロードしなおす場合です。
		// getCenter() / getLeftTopLatLng() 内などではこのメソッドを使ってはいけません。地図が崩れます。
		/*--------------------------------------------------*/
		//地図スクロルの移動量を求める
		var offset_y = this.oImgBufPosOrg.y - this.oImgBufPos.y;
		var offset_x = this.oImgBufPosOrg.x - this.oImgBufPos.x;
		if(offset_x==0&&offset_y==0){
			return;
		}
		var lat_sec = this.oCenterLatLng.lat_sec;
		var lng_sec = this.oCenterLatLng.lng_sec;
		//オフセット値を加減
		lat_sec = lat_sec - (this.lat_per_pix * offset_y);
		lng_sec = lng_sec + (this.lng_per_pix * offset_x);

		//有効範囲チェック
		if(this.validArea(lat_sec,lng_sec)==false){
			//範囲外のため更新せず終了
			return false;
		}
		//中心座標更新
		this.oCenterLatLng = new VMLatLng(lat_sec,lng_sec);
		//左上座標更新
		lat_sec = lat_sec + (this.lat_per_pix * this.oOutSize.height / 2);
		lng_sec = lng_sec - (this.lng_per_pix * this.oOutSize.width / 2);
		this.oLeftTopLatLng = new VMLatLng(lat_sec,lng_sec);
		//オフセット計算用変数更新
	    this.oImgBufPosOrg = new VMPoint(this.oImgBufPos.x,this.oImgBufPos.y);
		return true;
	},
	//=====================================================//
	// メソッド名（非公開）：validArea
	// 引数：lat_sec
	//     lng_sec
	// 戻り値：boolean - true:有効範囲内 false:範囲外
	// 機能：地図側で指定可能な座標の範囲かチェック
	//=====================================================//
	validArea : function(lat_sec,lng_sec){

		/*****************************/
		//2008/4/9 add
		var reSEC_LAT = new RegExp("^[0-9]{8,9}\.*[0-9]*$");
		var reSEC_LNG = new RegExp("^[0-9]{9}\.*[0-9]*$");
		//正規表現でチェックするため文字列に変換
		lat_args = String(lat_sec);
		lng_args = String(lng_sec);
		if(!lat_args.match(reSEC_LAT)){
			//範囲外のため更新せず終了
			//alert("フォーマット不正");
			return false;
		}
		if(!lng_args.match(reSEC_LNG)){
			//範囲外のため更新せず終了
			//alert("フォーマット不正");
			return false;
		}
		/*****************************/

	    // 地図側で指定可能な座標の範囲(緯度)
		var LAT_MIN  = 22.000000;
		var LAT_MAX = 48.400000;
	    // 地図側で指定可能な座標の範囲(経度)
		var LNG_MIN = 120.000000;
		var LNG_MAX = 152.000000;

		var latLng = new VMLatLng(lat_sec,lng_sec)
		if(latLng.lat_degree > LAT_MAX){
			//alert("latがMAX超");
			return　false;
		}
		if(latLng.lng_degree < LNG_MIN){
			//alert("lonがMIN未満");
			return　false;
		}
		if(latLng.lat_degree < LAT_MIN){
			//alert("latがMIN未満");
			return　false;
		}
		if(latLng.lng_degree > LNG_MAX){
			//alert("lonがMAX超");
			return　false;
		}
		return true;
	},
	//=====================================================//
	// メソッド名（非公開）：calcPerPix
	// 引数：なし
	// 戻り値：なし
	// 機能：1ピクセルあたりの緯度経度を計算し保持する。
	//=====================================================//
	bCalcPerPixFlg : true,//true:左上・右下の座標取得を連続で行う
	calcPerPix : function(){
		if(VMCommon.lat_per_pix[this.nScaleLevel]&&VMCommon.lat_per_pix[this.nScaleLevel]){
			//取得済み
			this.lat_per_pix = VMCommon.lat_per_pix[this.nScaleLevel];
			this.lng_per_pix = VMCommon.lng_per_pix[this.nScaleLevel];
			return;
		}
		//fetchLeftTopのAjax完了 → fetchRightBottomのAjax完了 →
		//completeRightBottomハンドラ内で1ピクセルあたりの緯度経度を計算し保持
		this.fetchLeftTop();
	},
	fetchLeftTop : function(){
		//alert("fetchLeftTop");
		//左上の緯度経度を取得（getMapPoint.cgi）
		var param = "CENTER_LAT=" + encodeURIComponent(this.oCenterLatLng.lat_padms);
		param += "&CENTER_LON=" + encodeURIComponent(this.oCenterLatLng.lng_padms);
		param += "&SCALE=" + this.nScaleLevel;
		param += "&SX=" + this.oOutSize.width;		//画面サイズ
		param += "&SY=" + this.oOutSize.height;		//画面サイズ
		param += "&WIN_X=0";
		param += "&WIN_Y=0";
		//同期
		VMCommon.ajaxPostData(VMDefine.POINTPROC, param, this.completeLeftTop.bindAsEventListener(this), VMCommon.failure, VMCommon.exeption,false);
	},
	fetchRightBottom : function(){
		//alert("fetchRightBottom");
		//右下の緯度経度を取得（getMapPoint.cgi）
		var param = "CENTER_LAT=" + encodeURIComponent(this.oCenterLatLng.lat_padms);
		param += "&CENTER_LON=" + encodeURIComponent(this.oCenterLatLng.lng_padms);
		param += "&SCALE=" + this.nScaleLevel;
		param += "&SX=" + this.oOutSize.width;		//画面サイズ
		param += "&SY=" + this.oOutSize.height;		//画面サイズ
		param += "&WIN_X=" + this.oOutSize.width;
		param += "&WIN_Y=" + this.oOutSize.height;
		//同期
		VMCommon.ajaxPostData(VMDefine.POINTPROC, param, this.completeRightBottom.bindAsEventListener(this), VMCommon.failure, VMCommon.exeption,false);
	},
	completeLeftTop :function(request){
		var res = request.responseText;
		if(!res){
			//範囲外の座標
			return;
		}
		var ary1 = res.split("=");
		var ary2 = ary1[1].split("/");
		this.oLeftTopLatLng = new VMLatLng(ary2[0],ary2[1]);
		if(this.bCalcPerPixFlg){
			//次のAjaxリクエスト
			this.fetchRightBottom();
			return;
		}
	} ,
	completeRightBottom :function(request){
		//alert("completeRightBottom");
		var res = request.responseText;
		var ary1 = res.split("=");
		var ary2 = ary1[1].split("/");
		this.oRightBottomLatLng = new VMLatLng(ary2[0],ary2[1]);

		//1ピクセルの重さ計算。1000ミリ秒
		var lat_sec1 = this.oLeftTopLatLng.lat_sec;
		var lng_sec1 = this.oLeftTopLatLng.lng_sec;
		var lat_sec2 = this.oRightBottomLatLng.lat_sec;
		var lng_sec2 = this.oRightBottomLatLng.lng_sec;
		this.lat_per_pix = Math.abs((lat_sec2 - lat_sec1) / this.oOutSize.height);
		this.lng_per_pix = Math.abs((lng_sec2 - lng_sec1) / this.oOutSize.width);
		
		VMCommon.lat_per_pix[this.nScaleLevel]=this.lat_per_pix;
		VMCommon.lng_per_pix[this.nScaleLevel]=this.lng_per_pix;
		
		//1mの重さ計算。1000ミリ秒
		//leftTopとrightTopの距離計算
//		var rightTop = new VMLatLng(this.oLeftTopLatLng.lat,this.oRightBottomLatLng.lng);
//		this.dist = this.oLeftTopLatLng.distanceFrom(rightTop);
//		this.per_meter = Math.abs((lng_sec2 - lng_sec1) / this.dist);
				
//		alert("lat_per_pix:" + this.lat_per_pix);
//		alert("lng_per_pix:" + this.lng_per_pix);
	} ,
	//=====================================================//
	// メソッド名：setZoom
	// 引数：level - ズームレベル
	// 戻り値：なし
	// 機能：ズームレベル設定
	//=====================================================//
	setZoom : function(level){
		//ルートシュミレーション実行中は実行しない
		if(this.onSimulating)return;
		if(this.nScaleLevel == level){
			return;	
		}
		if(!this.isLoaded()){
			this.nScaleLevel = level;
			if(this.scaleButtonInst!=null){
				this.scaleButtonInst.setButtons(this);
			}
			return;
		}
		//中心点設定更新
		if(this.calcCenter()==false){
			alert("地図表示の有効範囲外です");
			return;
		}
		//ズームレベル変更
		this.nScaleLevel = level;
		if(this.scaleButtonInst!=null){
			this.scaleButtonInst.setButtons(this);
		}
		//画像格納領域の設定
		this.setTileSettei(this.nScaleLevel);
		//画像格納領域を再作成
		this.createElemImgBuf();
		//左上・右下緯度経度を取得、1ピクセルあたりの緯度経度を計算して保持
		this.calcPerPix();
		//縮尺１，２の場合ロード後に中心点へ自動スクロールさせる
		// （ロードする前にスクロールすること。スクロール後の表示領域の地図をロードさせるため）
		this.scrollToCenter();
		//地図ロード
	    this.loadImage(this.oImgBufPos.x, this.oImgBufPos.y);
	    //アイコン再描画
	    this.addIcons(this.aIcons);
	},
	//=====================================================//
	// メソッド名：getZoom
	// 引数：なし
	// 戻り値：number - ズームレベル
	// 機能：ズームレベル取得
	//=====================================================//
	getZoom : function(){
		return this.nScaleLevel;
	},
	//=====================================================//
	// メソッド名：zoomIn
	// 引数：なし
	// 戻り値：なし
	// 機能：ズームレベル+1
	//=====================================================//
	zoomIn : function(){
		if(this.nSnScaleLevel < 12){
			this.setZoom(this.nScaleLevel+1);
		}
	},
	//=====================================================//
	// メソッド名：zoomOut
	// 引数：なし
	// 戻り値：なし
	// 機能：ズームレベル-1
	//=====================================================//
	zoomOut : function(){
		if(this.nSnScaleLevel > 1){
			this.setZoom(this.nScaleLevel-1);
		}
	},
	//-----------------------------------------------------//
	// メソッド名（非公開）：loadImage
	// 引数：x
	//       y
	// 戻り値：なし
	// 機能：画像ロード
	//-----------------------------------------------------//
	loadImage : function(x, y) {
		//CGIパラメータセット
		this.oReqParams.SCALE = this.nScaleLevel;
		this.oReqParams.CENTER_LAT = this.oCenterLatLng.lat_padms;
		this.oReqParams.CENTER_LON = this.oCenterLatLng.lng_padms;
		this.oReqParams.SX=this.oTileSize.width;//タイル（1枚の地図）のサイズ
		this.oReqParams.SY=this.oTileSize.height;//タイル（1枚の地図）のサイズ
	    var columns_s = 0;
	    if(x < 0) {
	        columns_s =  Math.floor( Math.abs(x) / this.oTileSize.width );
	    }
	    var columns_e =  Math.ceil( (this.oOutSize.width - x) / this.oTileSize.width );
	    if(columns_e > this.nTileColumns - 1)  {
	        columns_e = this.nTileColumns - 1;
	    }
	    var row_s = 0;
	    if(y < 0) {
	        row_s =  Math.floor( Math.abs(y) / this.oTileSize.height );
	    }
	    var row_e =  Math.ceil( (this.oOutSize.height - y) / this.oTileSize.height );
	    if(row_e > this.nTileRows - 1)  {
	        row_e = this.nTileRows - 1;
	    }
	    //ロード数カウンター
	    var nCnt = 0;
	    for(r = row_s; r <= row_e; r ++) {
	        for(c = columns_s; c <= columns_e; c ++) {
	            var tile_div_id = this.container.id + '_tile' + c + '_' + r;
	            var tile_div = $(tile_div_id);
	            if(this.aLoadedTiles[tile_div_id] == true) {
	            	//既読タイル
	                continue;
	            }
	            //tile_divにimg子要素があるかチェック
	            //なければ追加、あればsrcだけ書き換える
				if(tile_div.getElementsByTagName("img").length==0){
					var latLng = this.calcTileOffset(this.sfs_x[c],this.sfs_y[r]);
					//this.oReqParams.CENTER_LAT = latLng.lat_padms;
					//this.oReqParams.CENTER_LON = latLng.lng_padms;
					
					//有効範囲の座標チェック
					if(this.validArea(latLng.lat_sec,latLng.lng_sec)==false){
						tile_div.style.background = "#FFFFFF";
//						tile_div.innerHTML = latLng.lat_degree + "," + latLng.lng_degree;
						continue;
					}
			        var img = null;
		            img = document.createElement('img');
					tile_div.appendChild(img);//実行順変更。src設定する前にappend　2008/3/28 by kikuchi
		            img.width = this.oTileSize.width;
		            img.height = this.oTileSize.height;
		            img.src = VMDefine.MAPPROC +
	                this.oReqParams.getParams() +
		                '&OFF_X=' + this.sfs_x[c] +
		                '&OFF_Y=' + this.sfs_y[r] +
		                '';
//		            tile_div.appendChild(img);
		            this.aLoadedTiles[tile_div_id] = true;
//		            if(img.complete==false){
//		            	alert("ロードできません：" + tile_div.id);
//		            }
				}else{
					var img = tile_div.firstChild;
		            img.src = VMDefine.MAPPROC +
		                this.oReqParams.getParams() +
		                '&OFF_X=' + this.sfs_x[c] +
		                '&OFF_Y=' + this.sfs_y[r] +
		                '';
				}
				nCnt++;
	        }
	    }
//	    if(nCnt > 0){
//		    alert(nCnt + "枚ロードしています");
//	    }
		this.bLoaded = true;				
	},
 	//-----------------------------------------------------//
	// メソッド名（非公開）：calcTileOffset
	// 引数：off_x - タイルオフセットXコード
	//     off_y - タイルオフセットYコード
	// 戻り値：VMLatLng型
	// 機能：
	//-----------------------------------------------------//
	calcTileOffset : function(off_x,off_y){
		var tile_h_sec = this.lat_per_pix * this.oTileSize.height;
		var tile_w_sec = this.lng_per_pix * this.oTileSize.width;
		var lat_sec = this.oCenterLatLng.lat_sec;
		var lng_sec = this.oCenterLatLng.lng_sec;
		lat_sec = lat_sec + (off_y * tile_h_sec);
		lng_sec = lng_sec + (off_x * tile_w_sec);
		var latLng = new VMLatLng(lat_sec,lng_sec)
		return latLng;
	},
 	//----------------------------------------------------//
	// メソッド名（非公開）：createTileDiv
	// 引数：なし
	// 戻り値：なし
	// 機能：画像格納領域divを作成
	//-----------------------------------------------------//
    createTileDiv : function(){
	    var elemBuf = document.createElement('div');;
	    var r;
        var c;
		//画像格納領域初期化
	    for(r = 0; r < this.nTileRows; r ++) {
	        // 行
	        var row_div = document.createElement('div');
	        row_div.id = this.container.id + '_row' + r;
	        row_div.style.width = ( (this.oTileSize.width + 2) * this.nTileColumns ) + 'px';
	        row_div.style.height = this.oTileSize.height + 'px';
			row_div.style.zIndex = 10;
//	        row_div.style.background = "#66FFFF";
	        // CSSのclearプロパティーを'both'にセット
	        //row_div.style.clear = 'both';
	        for(c = 0; c < this.nTileColumns; c ++) {
	            // タイル
	            var tile_div = document.createElement('div');
	            tile_div.id = this.container.id + '_tile' + c + '_' + r;
	            tile_div.style.width = this.oTileSize.width + 'px';
	            tile_div.style.height = this.oTileSize.height + 'px';
	            // CSSのfloatプロパティーの値を'left'にセット
	            tile_div.style.styleFloat = 'left';  // IE,Opera用
	            tile_div.style.cssFloat = 'left'; // FireFox,Safari用
	            // デバッグ
//	            tile_div.style.color = '#000000';
//	            tile_div.innerHTML = tile_div.id;
//	            tile_div.style.border = '1px solid #000000';
	            row_div.appendChild(tile_div);
	        }
	        elemBuf.appendChild(row_div);
	    }
        return elemBuf;
	},
	//=====================================================//
	// メソッド名：addControl
	// 引数：VMDirectionControlまたはVMZoomControl　共通インタフェース作る方法？
	// 戻り値：なし
	// 機能：コントロールを追加する
	//=====================================================//
	addControl : function(control){
		//controlが必須メンバーを実装しているかチェック
		var aHissuMethod=new Array("id","createElem","removeElem","resize");
		var nCnt=0;
	    for (var member	 in control) {
			for(var i = 0; i < aHissuMethod.length;i++){
		        if (member==aHissuMethod[i]) {
					nCnt++;
		        }
			}
	    }
		if(aHissuMethod.length != nCnt){
			alert("addControlの引数は必須メンバーが実装されていません")
			return;
		}
		//elementの追加
		control.createElem(this);
		//配列に追加
		this.aControls.push(control);
		this.nControlSerial++;
		for (var i = 0; i < this.aControls.length; i++) {
			if (this.aControls[i].id != control.id) {
				//他のコントロールのリサイズ
				this.aControls[i].resize(this);
			}
		}
	},
	//=====================================================//
	// メソッド名：removeControl
	// 引数：VMDirectionControlまたはVMZoomControl　共通インタフェース作る方法？
	// 戻り値：なし
	// 機能：コントロールを削除する
	//=====================================================//
	removeControl : function(control){
		//elementの削除
		control.removeElem(this);
		var delIndex;
		for(var i = 0;i < this.aControls.length;i++){
			if(this.aControls[i].id == control.id){
				//削除するコントロールのインデックス
				delIndex = i;
			}else{
				//他のコントロールのリサイズ
				this.aControls[i].resize(this);
			}
		}
		//配列から削除
		this.aControls.splice(delIndex,1);
	},
	//=====================================================//
	// メソッド名：setMapMoving
	// 引数：direction - 矢印の方向（LU,CU,RU,L,R,LD,CD,RD）
	// 戻り値：なし
	// 機能：矢印クリックによる移動
	//=====================================================//
	setMapMoving : function(direction){
//		alert(direction);
		if(!direction)return;
		//ルートシュミレーション実行中は実行しない
		if(this.onSimulating)return;
		//度分秒から秒へ変換
		var lat_sec = this.oCenterLatLng.lat_sec;
		var lng_sec = this.oCenterLatLng.lng_sec;
		//矢印方向のオフセットを増減
		switch(direction){
			case "LU":
				lat_sec = lat_sec + (this.lat_per_pix * this.oOutSize.height / 2);
				lng_sec = lng_sec - (this.lng_per_pix * this.oOutSize.width / 2);
				this.oImgBufPos.y= this.oImgBufPos.y + (this.oOutSize.height / 2);
				this.oImgBufPos.x = this.oImgBufPos.x + (this.oOutSize.width / 2);
				break;
			case "CU":
				lat_sec = lat_sec + (this.lat_per_pix * this.oOutSize.height / 2);
				lng_sec = lng_sec;
				this.oImgBufPos.y= this.oImgBufPos.y + (this.oOutSize.height / 2);
				this.oImgBufPos.x = this.oImgBufPos.x;
				break;
			case "RU":
				lat_sec = lat_sec + (this.lat_per_pix * this.oOutSize.height / 2);
				lng_sec = lng_sec + (this.lng_per_pix * this.oOutSize.width / 2);
				this.oImgBufPos.y= this.oImgBufPos.y + (this.oOutSize.height / 2);
				this.oImgBufPos.x = this.oImgBufPos.x - (this.oOutSize.width / 2);
				break;
			case "L":
				lat_sec = lat_sec;
				lng_sec = lng_sec - (this.lng_per_pix * this.oOutSize.width / 2);
				this.oImgBufPos.y= this.oImgBufPos.y;
				this.oImgBufPos.x = this.oImgBufPos.x + (this.oOutSize.width / 2);
				break;
			case "R":
				lat_sec = lat_sec;
				lng_sec = lng_sec + (this.lng_per_pix * this.oOutSize.width / 2);
				this.oImgBufPos.y= this.oImgBufPos.y;
				this.oImgBufPos.x = this.oImgBufPos.x - (this.oOutSize.width / 2);
				break;
			case "LD":
				lat_sec = lat_sec - (this.lat_per_pix * this.oOutSize.height / 2);
				lng_sec = lng_sec - (this.lng_per_pix * this.oOutSize.width / 2);
				this.oImgBufPos.y= this.oImgBufPos.y - (this.oOutSize.height / 2);
				this.oImgBufPos.x = this.oImgBufPos.x + (this.oOutSize.width / 2);
				break;
			case "CD":
				lat_sec = lat_sec - (this.lat_per_pix * this.oOutSize.height / 2);
				lng_sec = lng_sec;
				this.oImgBufPos.y= this.oImgBufPos.y - (this.oOutSize.height / 2);
				this.oImgBufPos.x = this.oImgBufPos.x;
				break;
			case "RD":
				lat_sec = lat_sec - (this.lat_per_pix * this.oOutSize.height / 2);
				lng_sec = lng_sec + (this.lng_per_pix * this.oOutSize.width / 2);
				this.oImgBufPos.y= this.oImgBufPos.y - (this.oOutSize.height / 2);
				this.oImgBufPos.x = this.oImgBufPos.x - (this.oOutSize.width / 2);
				break;
			default:
				alert("error direction:" + direction);
				return;
		}
		//画像格納領域移動
		this.elemImgBuf.style.left = this.oImgBufPos.x + 'px';
		this.elemImgBuf.style.top = this.oImgBufPos.y + 'px';
		//スケール１、２はスクロールのみで抜ける
		if(this.nScaleLevel >= 1 && this.nScaleLevel <= 2){
			return;
		}
		//地図差分ロード
	    this.loadImage(this.oImgBufPos.x, this.oImgBufPos.y);
		if(this.endCheck()==false){
			//divの終端に達した場合
			//現在の中心点緯度経度計算（スクロール移動量計算）
			if(this.calcCenter()==false){
				alert("地図表示の有効範囲外です");
				return
			}
			//画像格納領域を削除、再作成
			this.createElemImgBuf();
			//地図ロード
		    this.loadImage(this.oImgBufPos.x, this.oImgBufPos.y);
			//左上・右下緯度経度を取得、1ピクセルあたりの緯度経度を計算して保持
			this.calcPerPix();
		    //アイコン再描画
		    this.addIcons(this.aIcons);
		}
	},
	//=====================================================//
	// メソッド名（非公開）：createElemImgBuf
	// 引数：なし
	// 戻り値：なし
	// 機能： 画像格納領域を作成／再作成
	//=====================================================//
	createElemImgBuf : function(){
		var p;//ポジション
		var z;//zIndex
		if($(this.container.id + "_imgBuf")){
			//画像格納領域 - style継承して削除
			var p = Element.getStyle(this.elemImgBuf,"position");
			var z = Element.getStyle(this.elemImgBuf,"zIndex");
			Element.remove(this.elemImgBuf);
		}else{
			var p = "relative";
			var z = "0";
		}
		//画像格納領域 - 作成
		this.elemImgBuf = this.createTileDiv();
		this.elemImgBuf.id = this.container.id + "_imgBuf";
		this.elemImgBuf.style.position = p; //スタイル継承
		this.elemImgBuf.style.zIndex = z;	//スタイル継承
		//既読タイル管理配列初期化
		this.aLoadedTiles = new Array();		
		//画像格納領域 - オフセット初期化
		this.initImgBufOffset();
		//画像格納領域 - 追加
		this.elemOut.appendChild(this.elemImgBuf);
	},
	//=====================================================//
	// メソッド名：addIcon
	// 引数：icon - VMIconオブジェクト
	//     kyosei - 強制再描画フラグ trueの時はaddIconEnabled()==falseでも再描画する
	// 戻り値：なし
	// 機能：アイコン等のプロット
	//=====================================================//
	addIcon : function(icon,kyosei){
		if(!kyosei){
			if(VMEvent.addIconEnabled()==false){
				return;
			}
		}
		//VMIconオブジェクトはpointとlatlngのどちらか一方か両方が設定されているので
		//一方からもう一方を計算
		if(!icon.point){
			icon.point = VMCommon.LatLngtoPOINT(this,icon.latlng);
		}else　if(!icon.latlng){
			icon.latlng = VMCommon.POINTtoLatLng(this,icon.point);
		}
		//アイコン管理配列登録チェック
		var bMatch = false;
		var icon_no;
		for(var i = 0;i < this.aIcons.length; i++){
			if(icon.equals(this.aIcons[i])){
				bMatch = true;
				icon_no = i;
				break;
			}
		}
		if(!bMatch){
			//-------------------------------------//
			//未登録の場合
			//-------------------------------------//
			icon_no = this.nIconSerial;
			this.aIcons.push(icon);
			this.nIconSerial++;
			//アイコン配置
			icon.plotIcon(this,icon_no);
		}else{
			//-------------------------------------//
			//登録済 ＝　移動／縮尺変更ボタンイベントの場合
			//-------------------------------------//
			//ウィンドウ座標が変更されたのでlatlngから計算し直し更新
			icon.point = VMCommon.LatLngtoPOINT(this,icon.latlng);
			//地図上のオフセット → imgBuf上のオフセット
			var x = (-icon.map.oImgBufPos.x) + icon.point.x;
			var y = (-icon.map.oImgBufPos.y) + icon.point.y;
			icon.oImgBufPoint = new VMPoint(x,y);
			//アイコン配置
			icon.plotIcon(this,icon_no);
			//噴出し再描画
			if(icon.oInfo!=null){
				if(icon.oInfo.elemInfoWin){
					icon.elemIcon.appendChild(icon.oInfo.elemInfoWin);
				}
				if(icon.oInfo.elemInfoWinLine){
					icon.elemIcon.appendChild(icon.oInfo.elemInfoWinLine);
					if(icon.oInfo.isShown()){
						icon.oInfo.show();
					}
				}
			}
			//ユーザーが設定したイベントを設定しなおす
			for(var i = 0;i < icon.aEvent.length;i++){
				VMEvent.addEventListener(icon,icon.aEvent[i],icon.aEventHandler[i]);
			}
		}
	},
	//=====================================================//
	// メソッド名：removeIcon
	// 引数：icon - VMIcon
	// 戻り値：なし
	// 機能：アイコン等の削除
	//=====================================================//
	removeIcon : function(icon){ 
		//要素を削除
		icon.removeElem(this);
		//配列から削除
		for(var i = 0;i < this.aIcons.length; i++){
			if(this.aIcons[i].id == icon.id){
				this.aIcons.splice(i,1);
				break;
			}
		}
	},
	//=====================================================//
	// メソッド名：clearIcons
	// 引数：なし
	// 戻り値：なし
	// 機能：アイコンの一括削除
	//=====================================================//
	clearIcons : function(){
		var nCnt = this.aIcons.length;
		for(var i = 0;i < nCnt; i++){
			//要素を削除
			this.aIcons[i].removeElem(this);
		}
		//配列を初期化
		this.aIcons = new Array();
		this.nIconSerial=0;
	},
	//=====================================================//
	// メソッド名：addIcons
	// 引数：aIcons - VMIconオブジェクトの配列
	// 戻り値：なし
	// 機能：アイコンの一括追加
	//=====================================================//
	addIcons : function(aIcons){
		if(aIcons.length==0)return;
		for(var i = 0;i < aIcons.length; i++){
			this.addIcon(aIcons[i],true);
		}
	}
}

//=====================================================//
//VMParamsクラス　地図表示用パラメータ
//=====================================================//
var VMParams = Class.create();
VMParams.prototype = {

	//=====================================================//
	// コンストラクタ
	// 引数：oTileSize - タイルサイズ
	//	   scale - スケールレベル
	// 戻り値：VMParamsインスタンス
	// 機能：初期化
	//=====================================================//
	initialize : function() { 
			this.USER="jafnavi";
			this.CENTER_LAT="";
			this.CENTER_LON="";
			this.SCALE="";
			this.SX="";
			this.SY="";
			this.ROUTE="0";
			this.JAM_E="0000";
			this.JAM_C="0000";
			this.JAM_G="0000";
			this.JAM_O="0000";
			this.JAM_FS_E="0000";
			this.JAM_FS_C="0000";
			this.JAM_FS_G="0000";
			this.JAM_FS_O="0000";
			this.ACCIDENT="0000";
			this.MARK="";
			this.MARKPATH="";
			this.CIRCLE="";
			this.POLYLINE="";
			this.POLYGON="";
			this.MARKFILE="";
			this.FIGFILE="";
			this.FMT="0";//出力形式　0:GIF形式(46.9 KB) 1:PNG形式(40.7 KB)
			this.DATE="";
			this.OFF_X="";
			this.OFF_Y="";
			this.DRAWMARK="";
	},
	//=====================================================//
	// メソッド名（非公開）：getParams
	// 引数：なし
	// 戻り値：パラメータ文字列
	// 機能：パラメータ文字列取得
	//=====================================================//
	getParams : function(){
		return "?USER=" + this.USER +
			"&CENTER_LAT=" + encodeURIComponent(this.CENTER_LAT) + 
			"&CENTER_LON=" + encodeURIComponent(this.CENTER_LON) +
			"&SCALE=" + this.SCALE +
			"&SX=" + this.SX +
			"&SY=" + this.SY +
			"&ROUTE=" + this.ROUTE +
			"&JAM_E=" + this.JAM_E +
			"&JAM_C=" + this.JAM_C +
			"&JAM_G=" + this.JAM_G +
			"&JAM_O=" + this.JAM_O + 
			"&JAM_FS_E=" + this.JAM_FS_E +
			"&JAM_FS_C=" + this.JAM_FS_C +
			"&JAM_FS_G=" + this.JAM_FS_G +
			"&JAM_FS_O=" + this.JAM_FS_O +
			"&ACCIDENT=" + this.ACCIDENT +	
			"&MARK=" + this.MARK +
			"&MARKPATH=" + this.MARKPATH +
			"&CIRCLE=" + this.CIRCLE +
			"&POLYLINE=" + this.POLYLINE +
			"&POLYGON=" + this.POLYGON +
			"&MARKFILE=" + this.MARKFILE +
			"&FIGFILE=" + this.FIGFILE +
			"&FMT=" + this.FMT +
			"&DATE=" + this.DATE + 
			"&DRAWMARK=" + this.DRAWMARK;
	}
}
//=====================================================//
//VMInfoクラス
//=====================================================//
var VMInfo = Class.create();
VMInfo.prototype = {
	//=====================================================//
	// コンストラクタ
	// 引数：icon - 親アイコンインスタンス
	// 戻り値：VMInfoクラスインスタンス
	// 機能：初期化
	//=====================================================//
	initialize: function(icon){	
		this.typename = "VMInfo";
		this.icon = icon;
		this.map = icon.map;
		this.infoWinAnchor;
		this.elemInfoWin;
		this.id = "";
		this.bShow = false;
		this.bDrag = true;
		this.sFukidashiDir = "";
		this.sZone = "";
		this.contents = "";
		
		//----------------//
		//噴出し追加
		//----------------//
		this.id = this.icon.id + "_info";;
		this.elemInfoWin = document.createElement("div");
		this.infoWinAnchor = icon.infoWinAnchor;
		this.elemInfoWin.id = this.id;
		this.elemInfoWin.style.position = "absolute";
		this.elemInfoWin.style.display = "none";
		this.elemInfoWin.style.zIndex = 1000;
		this.elemInfoWin.top = 0;
		this.elemInfoWin.left = 0;
		this.icon.elemIcon.appendChild(this.elemInfoWin);

		//-----------------//
		//デフォルトサイズ設定
		//-----------------//
		this.setWinSize(10,10);
		
		//----------------//
		//線描画領域
		//----------------//
		this.elemInfoWinLine = document.createElement("div");
		this.elemInfoWinLine.id = this.id + "_line";
		this.elemInfoWinLine.top = 0;
		this.elemInfoWinLine.left = 0;
		this.elemInfoWinLine.posision = "absolute";
		this.elemInfoWinLine.style.zIndex = 0;
		this.icon.elemIcon.appendChild(this.elemInfoWinLine);

		//----------------//
		//コンテンツ部分
		//----------------//
		this.elemContents = document.createElement("div");
		this.elemContents.id = this.id + "_contents";
//		this.elemContents.style.fontSize = "11pt";
		this.elemContents.style.top = "0px";
		this.elemContents.style.left = "0px";
//		this.elemContents.style.margin = "5px";
		this.elemContents.style.position = "absolute";
///		this.elemContents.style.zIndex = 1111;
		this.elemInfoWin.appendChild(this.elemContents);
		
		if(this.bDrag){
//			this.enableDragging(this.map);
			VMEvent.addInfoWinDraggingListener(this);
		}
	},
	//=====================================================//
	// メソッド名：isShown
	// 引数：なし
	// 戻り値：boolean
	// 機能：表示設定されている場合trueを返す
	//=====================================================//
	isShown : function(){
		return this.bShow;
	},
	//=====================================================//
	// メソッド名：enableDragging
	// 引数：map - VMapインスタンス
	// 戻り値：なし
	// 機能：ドラッグ可能に設定
	//=====================================================//
	enableDragging : function(map){
//		if(!map){
			//alert("enableDragging　引数異常");
//			return;
//		}
		this.bDrag = true;
//		VMEvent.addInfoWinDraggingListener(this);
	},
	//=====================================================//
	// メソッド名：disableDragging
	// 引数：なし
	// 戻り値：なし
	// 機能：ドラッグ不可に設定
	//=====================================================//
	disableDragging : function(){
		this.bDrag = false;
	}, 
	//=====================================================//
	// メソッド名：draggingEnabled
	// 引数：なし
	// 戻り値：Boolean
	// 機能：ドラッグ可／不可を取得
	//=====================================================//
	draggingEnabled : function(){
		return this.bDrag;
	},
	//=====================================================//
	// メソッド名：setWinSize
	// 引数：width  - 幅 
	//     height -　高さ
	// 戻り値：なし
	// 機能：elemInfoWinのサイズ設定・再設定
	//=====================================================//
	setWinSize : function(width,height){
		this.size = new VMSize(width,height);
		this.elemInfoWin.width = this.size.width;
		this.elemInfoWin.height = this.size.height;
		this.elemInfoWin.style.width = this.elemInfoWin.width + "px";
		this.elemInfoWin.style.height = this.elemInfoWin.height + "px";
	},
	//-----------------------------------------------------//
	// メソッド名（非公開）：show
	// 引数：Optional contents - コメント（innerHtmlに挿入）
	// 戻り値：なし
	// 機能：噴出し表示
	//-----------------------------------------------------//
	show : function(contents){
		//コンテンツ挿入
		if(contents && contents != this.contents){
			this.contents = contents;
			this.elemContents.innerHTML = this.contents;
		}
		
		//showしてからoffsetWidthで取得してコンテンツのサイズにあったサイズに再設定する
		Element.show(this.elemInfoWin);
		this.bShow = true;
		this.setWinSize(this.elemContents.offsetWidth,this.elemContents.offsetHeight);
		
		//表示位置設定
		if(this.elemInfoWin.top!=0 && this.elemInfoWin.left != 0){
			//設定済みの場合
			// 罫線描画
			this.clearLine();
			this.drawLine();

			//マウスオーバーイベント設定
			VMEvent.addEventListener(this.elemInfoWin,"mouseover",VMEvent.disableAddIcon);
			VMEvent.addEventListener(this.elemInfoWin,"mouseout",VMEvent.enableAddIcon);
			
			return;
		}	

		//表示位置未設定。デフォルト表示位置設定
		//ゾーン判定 LU:左上,UC:上;RU:右上,CL:中左,CC:中,CR:中右,LD:左下,CD:中下,RD:右下
		var row_w = this.map.oOutSize.width / 3;
		if(this.icon.oImgBufPoint.x - (-this.map.oImgBufPos.x)  < row_w){
			this.sZone = "L";
		}else if(this.icon.oImgBufPoint.x - (-this.map.oImgBufPos.x) < row_w * 2){
			this.sZone = "C";
		}else{
			this.sZone = "R";
		}
		var col_w = this.map.oOutSize.height / 3;
		if(this.icon.oImgBufPoint.y - (-this.map.oImgBufPos.y) < col_w){
			this.sZone = this.sZone + "U";
		}else if(this.icon.oImgBufPoint.y - (-this.map.oImgBufPos.y) < col_w * 2){
			this.sZone = this.sZone + "C";
		}else{
			this.sZone = this.sZone + "D";
		}

		this.icon.infoWinAnchor = new VMPoint(50,50);

		switch(this.sZone){
			case "LU":
				this.elemInfoWin.top = 0;
				this.elemInfoWin.left = this.icon.infoWinAnchor.x;
				break;
			case "CU":
				this.elemInfoWin.top = this.icon.infoWinAnchor.y;
				this.elemInfoWin.left = -(this.elemInfoWin.width / 2);
				break;
			case "RU":
				this.elemInfoWin.top = 0;
				this.elemInfoWin.left = -(this.icon.infoWinAnchor.x + this.elemInfoWin.width);
				break;
			case "LC":
				this.elemInfoWin.top = -(this.elemInfoWin.height / 2);
				this.elemInfoWin.left = this.icon.infoWinAnchor.x;
				break;
			case "CC":
				this.elemInfoWin.top = this.icon.infoWinAnchor.y;
				this.elemInfoWin.left = -(this.elemInfoWin.width / 2);
				break;
			case "RC":
				this.elemInfoWin.top = -(this.elemInfoWin.height / 2);
				this.elemInfoWin.left = -(this.icon.infoWinAnchor.x + this.elemInfoWin.width);
				break;
			case "LD":
				this.elemInfoWin.top = -(this.elemInfoWin.height);
				this.elemInfoWin.left = this.icon.infoWinAnchor.x;
				break;
			case "CD":
				this.elemInfoWin.top = -(this.elemInfoWin.height + this.icon.infoWinAnchor.y);
				this.elemInfoWin.left = -(this.elemInfoWin.width / 2);
				break;
			case "RD":
				this.elemInfoWin.top = -(this.elemInfoWin.height);
				this.elemInfoWin.left = -(this.icon.infoWinAnchor.x + this.elemInfoWin.width);
				break;
		}
		this.elemInfoWin.style.top = this.elemInfoWin.top + "px";
		this.elemInfoWin.style.left = this.elemInfoWin.left + "px";

		// 罫線描画
		this.clearLine();
		this.drawLine();

		//マウスオーバーイベント設定
		VMEvent.addEventListener(this.elemInfoWin,"mouseover",VMEvent.disableAddIcon);
		VMEvent.addEventListener(this.elemInfoWin,"mouseout",VMEvent.enableAddIcon);

	},
	//-----------------------------------------------------//
	// メソッド名（非公開）：hide
	// 引数：なし
	// 戻り値：なし
	// 機能：噴出し非表示
	//-----------------------------------------------------//
	hide : function(){
		Element.hide(this.elemInfoWin);
		this.clearLine();
		this.bShow = false;
	},
	//-----------------------------------------------------//
	// メソッド名（非公開）：drawLine
	// 引数：なし
	// 戻り値：なし
	// 機能：アイコンと噴出しを罫線で結ぶ
	//-----------------------------------------------------//
	drawLine : function(){
//		var x1 = this.icon.oImgBufPoint.x;
//		var y1 = this.icon.oImgBufPoint.y;
		var x1 = this.icon.iconAnchor.x;
		var y1 = this.icon.iconAnchor.y;
		var x2 = this.elemInfoWin.left + (this.elemInfoWin.width / 2);
		var y2 = this.elemInfoWin.top + (this.elemInfoWin.height / 2);
		var jgObj;
		jgObj = new jsGraphics(this.elemInfoWinLine.id);
		jgObj.setColor("#000000");
		jgObj.setStroke(1);
		jgObj.drawLine(x1,y1,x2,y2);
		jgObj.paint();
	},
	//-----------------------------------------------------//
	// メソッド名（非公開）：clearLine
	// 引数：なし
	// 戻り値：なし
	// 機能：子要素を削除。自身は削除しない
	//-----------------------------------------------------//
	clearLine: function(){
		var oElements = this.elemInfoWinLine.childNodes; 
		for (var i = 0; i < oElements.length; i++) {
			Element.remove(oElements[i]);
		}
	}
}


//=====================================================//
//VMIconクラス
//=====================================================//
var VMIcon = Class.create();
VMIcon.prototype = {
	//=====================================================//
	// コンストラクタ
	// 引数：arg1 - 型は次のどちらか
	//			1. VMLatLng - 緯度経度
	//			2. VMPoint - 地図表示領域WIN座標
	//     size  - アイコンサイズ（VMSize型）
	//     iconAnchor - アイコンのアンカーポイント（VMPoint型）
	//     image  - アイコン画像 デフォルト：VMDefine.DEFAULT_ICON
	// 戻り値：VMIconクラスインスタンス
	// 機能：初期化
	//=====================================================//
	initialize: function(arg1,size,iconAnchor,image){
		this.typename = "VMIcon";
		if(arg1.typename=="VMLatLng"){
			this.latlng = arg1;
			this.point = null;
		}else if(arg1.typename =="VMPoint"){
			this.point = arg1;
			this.latlng = null;//VMLatLng型
		}else{
			alert("VMIcon 引数の型が不正です:" + arg1.typename);
			return;
		}
		this.id = "";
		this.iconAnchor = iconAnchor;
		this.size = size;
		this.image = image;
		this.elemIcon;
		this.bHidden = true;
		this.bDrag = false;
		this.sFukidashiDir = "";
		this.infoWinAnchor;//VMPoint型
		this.sZone;//LU:左上,CU:中上;RU:右上,LD:左下,CD:中下,RD:右下
		this.bInfoOpen = false;
		this.elemInfoWin;
		this.oInfo = null;//噴出し
		this.oImgBufPoint = null;//イメージ格納領域におけるWIN座標
		this.aEvent = new Array();//addEventListnerされたEventを管理
		this.aEventHandler = new Array();//addEventListnerされたEventを管理

		//アイコン格納領域作成
		this.elemIcon = document.createElement("div");
		this.elemIcon.style.position = "absolute";
	    this.elemIcon.style.cursor = "pointer";
		this.elemIcon.style.zIndex = 1000;

		//アイコン画像追加
		this.img = document.createElement("img");
		this.img.src = VMDefine.ImgDir + this.image;
		this.img.style.position = "relative";//position: relative を指定しておかないとz-indexの指定が効かない(z-indexはpositionがstatic以外の要素にしか効果がない） 
		this.img.style.zIndex = 1000;
		this.elemIcon.appendChild(this.img);

		//ドラッグ設定
		this.bAddedEvent = false;
	},
	//=====================================================//
	// メソッド名：getPoint
	// 引数：なし
	// 戻り値：VMPoint - 地図表示領域内WIN座標
	// 機能：WIN座標取得
	//=====================================================//
	getPoint : function(){
		var offset_y = 0;
		var offset_x = 0;
		//地図スクロールの移動量を求める 2008/5/28 add
		if(this.map.nScaleLevel > 3){
			offset_y = this.map.oImgBufPosOrg.y - this.map.oImgBufPos.y;
			offset_x = this.map.oImgBufPosOrg.x - this.map.oImgBufPos.x;			
		}
		var y = this.point.y - offset_y;
		var x = this.point.x - offset_x;
		//小数点四捨五入　2008/5/29 add
		x = Math.round(x);
		y = Math.round(y);
		return new VMPoint(x,y);
	},
	//=====================================================//
	// メソッド名：getLatLng
	// 引数：なし
	// 戻り値：VMLatLng - 緯度経度
	// 機能：緯度経度取得
	//=====================================================//
	getLatLng : function(){
		return this.latlng;
	},
	//=====================================================//
	// メソッド名：getInfoWinPos
	// 引数：なし
	// 戻り値：VMPointインスタンス　- 噴出しのウィンドウ座標（アイコンとの相対位置）
	// 機能：噴出し位置取得
	//=====================================================//
	getInfoWinPos : function(){
		var x = this.oInfo.elemInfoWin.left - this.iconAnchor.x;
		var y = this.oInfo.elemInfoWin.top - this.iconAnchor.y;
		return new VMPoint(x,y);
	},
	//=====================================================//
	// メソッド名：setInfoWinPos
	// 引数：x,y
	// 戻り値：なし
	// 機能：噴出し位置指定して表示
	//=====================================================//
	setInfoWinPos : function(x, y){
		if(isNaN(x) || isNaN(y)) return;
		this.oInfo.elemInfoWin.left = Number(x) + this.iconAnchor.x;;
		this.oInfo.elemInfoWin.top  = Number(y) + this.iconAnchor.y;;
		this.oInfo.elemInfoWin.style.top =  this.oInfo.elemInfoWin.top + "px";
		this.oInfo.elemInfoWin.style.left = this.oInfo.elemInfoWin.left + "px";
		this.oInfo.show();
	},
	//=====================================================//
	// メソッド名：enableDragging
	// 引数：map - VMapインスタンス
	// 戻り値：なし
	// 機能：ドラッグ可能に設定
	//=====================================================//
	enableDragging : function(map){
		if(!map){
			alert("enableDragging　引数異常");
			return;
		}
		this.bDrag = true;
	    this.elemIcon.style.cursor = "move";
	    if(this.bAddedEvent == false){
			VMEvent.addIconDraggingListener(map,this);
			this.bAddedEvent = true;
	    }
	},
	//=====================================================//
	// メソッド名：disableDragging
	// 引数：なし
	// 戻り値：なし
	// 機能：ドラッグ不可に設定
	//=====================================================//
	disableDragging : function(){
	    this.elemIcon.style.cursor = "pointer";
		this.bDrag = false;
	}, 
	//=====================================================//
	// メソッド名：draggingEnabled
	// 引数：なし
	// 戻り値：Boolean
	// 機能：ドラッグ可／不可を取得
	//=====================================================//
	draggingEnabled : function(){
		return this.bDrag;
	}, 
	//=====================================================//
	// メソッド名：setInfoWindow
	// 引数：oInfo - VMInfoオブジェクト
	// 戻り値：なし
	// 機能：
	//=====================================================//
	setInfoWindow : function(oInfo){
		this.oInfo=oInfo;
	},
	//=====================================================//
	// メソッド名：openInfoWindow
	// 引数：Optional contents - コメント（innerHtmlに挿入）
	// 戻り値：なし
	// 機能：
	//=====================================================//
	openInfoWindow : function(map,contents){
		if(!this.oInfo){
			this.oInfo = new VMInfo(this);
		}
		if(contents){
			//コンテンツ上書き
			this.oInfo.show(contents);
		}else{
			this.oInfo.show();
		}
	},
	//=====================================================//
	// メソッド名：closeInfoWindow
	// 引数：なし
	// 戻り値：なし
	// 機能：
	//=====================================================//
	closeInfoWindow : function(contents){
		if(this.oInfo==null){
			return;
		}
		this.oInfo.hide();
	},
	//-----------------------------------------------------//
	// メソッド名（非公開）：plotIcon
	// 引数：inst - VMapインスタンス
	// 戻り値：なし
	// 機能：アイコン描画
	//-----------------------------------------------------//
	plotIcon: function(map,icon_no){
		
		this.id = map.container.id + "_icon" + icon_no;
		this.map = map;
		this.img.id = map.container.id + "_icon" + icon_no + "Img";

		//地図上のオフセット → imgBuf上のオフセット
		var x = (-this.map.oImgBufPos.x) + this.point.x;
		var y = (-this.map.oImgBufPos.y) + this.point.y;
		this.oImgBufPoint = new VMPoint(x,y);
		
		this.elemIcon.id = this.id;
		this.elemIcon.style.top = this.oImgBufPoint.y - this.iconAnchor.y + "px";
		this.elemIcon.style.left =this.oImgBufPoint.x - this.iconAnchor.x + "px";
		map.elemImgBuf.appendChild(this.elemIcon);		
		this.bHidden = false;

	},
	//-----------------------------------------------------//
	// メソッド名（非公開）：removeElem
	// 引数：inst - VMapインスタンス
	// 戻り値：なし
	// 機能：アイコン削除
	//-----------------------------------------------------//
	removeElem : function(map){
		if(this.elemIcon)Element.remove(this.elemIcon);
		if(this.oInfo!=null){
			if(this.oInfo.elemInfoWin)Element.remove(this.oInfo.elemInfoWin);
			if(this.oInfo.elemInfoWinLine)Element.remove(this.oInfo.elemInfoWinLine);
		}
	},
	//-----------------------------------------------------//
	// メソッド名（非公開）：show
	// 引数：inst - VMapインスタンス
	// 戻り値：なし
	// 機能：アイコン表示
	//-----------------------------------------------------//
	show: function(map){
		if(this.elemIcon)Element.show(this.elemIcon);
		if(this.oInfo!=null){
			if(this.oInfo.elemInfoWin)Element.show(this.oInfo.elemInfoWin);
			if(this.oInfo.elemInfoWinLine)Element.show(this.oInfo.elemInfoWinLine);
		}
		this.bHidden = false;
	},
	//-----------------------------------------------------//
	// メソッド名（非公開）：hide
	// 引数：inst - VMapインスタンス
	// 戻り値：なし
	// 機能：アイコン非表示
	//-----------------------------------------------------//
	hide : function(map){
		if(this.elemIcon)Element.hide(this.elemIcon);
		if(this.oInfo!=null){
			if(this.oInfo.elemInfoWin)Element.hide(this.oInfo.elemInfoWin);
			if(this.oInfo.elemInfoWinLine)Element.hide(this.oInfo.elemInfoWinLine);
		}
		this.bHidden = true;
	},
	//-----------------------------------------------------//
	// メソッド名（非公開）：isHidden
	// 引数：inst - VMapインスタンス
	// 戻り値：Boolean
	// 機能：アイコン非表示かどうか
	//-----------------------------------------------------//
	isHidden : function(){
		return this.bHidden;		
	},
	//-----------------------------------------------------//
	// メソッド名（非公開）：equals
	// 引数：other - VMIconオブジェクト
	// 戻り値：Boolean
	// 機能：同じオブジェクトか比較する
	//-----------------------------------------------------//
	equals: function(other){
		if(this === other){
			return true;
		}
		return false;
	}
}

//=====================================================//
// VMDirectionControlクラス
//=====================================================//
var VMDirectionControl = Class.create();
VMDirectionControl.prototype = {
	//=====================================================//
	// コンストラクタ
	// 引数：なし
	// 戻り値：VMDirectionControlのインスタンス
	// 機能：
	//=====================================================//
	initialize: function(){
		this.typename = "VMDirectionControl";
		VMInstances.setInstance(this);
		this.id = "";
		this.elemTopArrow;
		this.elemLeftArrow;
		this.elemRightArrow;
		this.elemBottomArrow;
		this.ImgFiles = {						//紫の矢印シリーズ
				ImgArrow1 : VMDefine.ImgDir + "dp_mapl_c1.gif",
				ImgArrow2 : VMDefine.ImgDir + "dp_mapl_c2.gif",
				ImgArrow3 : VMDefine.ImgDir + "dp_mapl_c3.gif",
				ImgArrow4 : VMDefine.ImgDir + "dp_mapl_c4.gif",
				ImgArrow5 : VMDefine.ImgDir + "dp_mapl_c5.gif",
				ImgArrow6 : VMDefine.ImgDir + "dp_mapl_c6.gif",
				ImgArrow7 : VMDefine.ImgDir + "dp_mapl_c7.gif",
				ImgArrow8 : VMDefine.ImgDir + "dp_mapl_c8.gif"
		};
	},
 	//-----------------------------------------------------//
	// メソッド名（非公開）：removeElem
	// 引数：inst - VMapインスタンス
	// 戻り値：なし
	// 機能：上下左右の矢印移動コントロールを無効にする
	//-----------------------------------------------------//
	removeElem : function(inst){
		if(this.elemTopArrow)Element.remove(this.elemTopArrow);
		if(this.elemLeftArrow)Element.remove(this.elemLeftArrow);
		if(this.elemRightArrow)Element.remove(this.elemRightArrow);
		if(this.elemBottomArrow)Element.remove(this.elemBottomArrow);
		//表示領域のリサイズ
		inst.elemOut.style.width = inst.container.style.width;
		inst.elemOut.style.height = inst.container.style.height;
		inst.elemOut.style.top = inst.container.style.top;
		inst.elemOut.style.left = inst.container.style.left;
		inst.oOutParentOffset = new VMPoint(0,0);
		var w = VMCommon.getNumber(inst.elemOut.style.width);
		var h = VMCommon.getNumber(inst.elemOut.style.height);
		inst.changeOutSize( new VMSize(w,h));
	},
 	//-----------------------------------------------------//
	// メソッド名（非公開）：createElem
	// 引数：inst - VMapインスタンス
	// 戻り値：なし
	// 機能：上下左右の矢印移動コントロールを有効にする
	//-----------------------------------------------------//
	createElem : function(inst){
		this.id = inst.container.id + "_arrows";
		//---------------------------------
		//上方向矢印領域
		//---------------------------------
		this.elemTopArrow = document.createElement("div");
		this.elemTopArrow.id = inst.container.id + "_topArrow" + inst.nControlSerial;
		this.elemTopArrow.style.position = "absolute";
//		this.elemTopArrow.style.background = "#ACB2EC";
		this.elemTopArrow.style.background = "#999999";
		//左上
		this.elemArrow1 = document.createElement("div");
		this.elemArrow1.style.position = "absolute";
		var img1 = document.createElement("img");
        img1.src = this.ImgFiles["ImgArrow1"];
		img1.alt = "左上";
		img1.style.width = "16px";
		img1.style.height = "16px";
		VMCommon.setAttribute(img1,"onclick","VMEvent.directionChangeHandler(" + VMInstances.getInstNumber(inst) + "," + VMInstances.getInstNumber(this) + ",'LU')");
        this.elemArrow1.appendChild(img1);
		//上
		this.elemArrow2 = document.createElement("div");
		this.elemArrow2.style.position = "absolute";
		var img2 = document.createElement("img");
		img2.src = this.ImgFiles["ImgArrow2"];
		img2.alt = "上";
		img2.style.width = "16px";
		img2.style.height = "16px";
		VMCommon.setAttribute(img2,"onclick","VMEvent.directionChangeHandler(" + VMInstances.getInstNumber(inst) + "," + VMInstances.getInstNumber(this) + ",'CU')");
        this.elemArrow2.appendChild(img2);
		//右上
		this.elemArrow3 = document.createElement("div");
		this.elemArrow3.style.position = "absolute";
		var img3 = document.createElement("img");
		img3.src = this.ImgFiles["ImgArrow3"];
		img3.alt = "右上";
		img3.style.width = "16px";
		img3.style.height = "16px";
		VMCommon.setAttribute(img3,"onclick","VMEvent.directionChangeHandler(" + VMInstances.getInstNumber(inst) + "," + VMInstances.getInstNumber(this) + ",'RU')");
        this.elemArrow3.appendChild(img3);
		//追加
		this.elemTopArrow.appendChild(this.elemArrow1);
		this.elemTopArrow.appendChild(this.elemArrow2);
		this.elemTopArrow.appendChild(this.elemArrow3);
		//---------------------------------
		//左方向矢印領域
		//---------------------------------
		this.elemLeftArrow = document.createElement("div");
		this.elemLeftArrow.id = inst.container.id + "_leftArrow";
		this.elemLeftArrow.style.position = "absolute";
//		this.elemLeftArrow.style.background = "#ACB2EC";
		this.elemLeftArrow.style.background = "#999999";
		this.elemArrow4 = document.createElement("div");
		this.elemArrow4.style.position = "absolute";
		var img4 = document.createElement("img");
		img4.src = this.ImgFiles["ImgArrow4"];
		img4.alt = "左";
		img4.style.width = "16px";
		img4.style.height = "16px";
		VMCommon.setAttribute(img4,"onclick","VMEvent.directionChangeHandler(" + VMInstances.getInstNumber(inst) + "," + VMInstances.getInstNumber(this) + ",'L')");
        this.elemArrow4.appendChild(img4);
		this.elemLeftArrow.appendChild(this.elemArrow4);
		//---------------------------------
		//右方向矢印領域
		//---------------------------------
		this.elemRightArrow = document.createElement("div");
		this.elemRightArrow.id = inst.container.id + "_rightArrow";
		this.elemRightArrow.style.position = "absolute";
//		this.elemRightArrow.style.background = "#ACB2EC";
		this.elemRightArrow.style.background = "#999999";
		this.elemArrow5 = document.createElement("div");
		this.elemArrow5.style.position = "absolute";
		var img5 = document.createElement("img");
		img5.src = this.ImgFiles["ImgArrow5"];
		img5.alt = "右";
		img5.style.width = "16px";
		img5.style.height = "16px";
		VMCommon.setAttribute(img5,"onclick", "VMEvent.directionChangeHandler(" + VMInstances.getInstNumber(inst) + "," + VMInstances.getInstNumber(this) + ",'R')");
        this.elemArrow5.appendChild(img5);
		this.elemRightArrow.appendChild(this.elemArrow5);
		//---------------------------------
		//下方向矢印領域
		//---------------------------------
		this.elemBottomArrow = document.createElement("div");
		this.elemBottomArrow.id = inst.container.id + "_bottomArrow";
		this.elemBottomArrow.style.position = "absolute";
//		this.elemBottomArrow.style.background = "#ACB2EC";
		this.elemBottomArrow.style.background = "#999999";
		//左下
		this.elemArrow6 = document.createElement("div");
		this.elemArrow6.style.position = "absolute";
		var img6 = document.createElement("img");
		img6.src = this.ImgFiles["ImgArrow6"];
		img6.alt = "左下";
		img6.style.width = "16px";
		img6.style.height = "16px";
		VMCommon.setAttribute(img6,"onclick", "VMEvent.directionChangeHandler(" + VMInstances.getInstNumber(inst) + "," + VMInstances.getInstNumber(this) + ",'LD')");
        this.elemArrow6.appendChild(img6);
		//下
		this.elemArrow7 = document.createElement("div");
		this.elemArrow7.style.position = "absolute";
		var img7 = document.createElement("img");
		img7.src = this.ImgFiles["ImgArrow7"];
		img7.alt = "下";
		img7.style.width = "16px";
		img7.style.height = "16px";
		VMCommon.setAttribute(img7,"onclick", "VMEvent.directionChangeHandler(" + VMInstances.getInstNumber(inst) + "," + VMInstances.getInstNumber(this) + ",'CD')");
        this.elemArrow7.appendChild(img7);
		//右下
		this.elemArrow8 = document.createElement("div");
		this.elemArrow8.style.position = "absolute";
		var img8 = document.createElement("img");
		img8.src = this.ImgFiles["ImgArrow8"];
		img8.alt = "右下";
		img8.style.width = "16px";
		img8.style.height = "16px";
		VMCommon.setAttribute(img8,"onclick", "VMEvent.directionChangeHandler(" + VMInstances.getInstNumber(inst) + "," + VMInstances.getInstNumber(this) + ",'RD')");
        this.elemArrow8.appendChild(img8);

		//追加
		this.elemBottomArrow.appendChild(this.elemArrow6);
		this.elemBottomArrow.appendChild(this.elemArrow7);
		this.elemBottomArrow.appendChild(this.elemArrow8);

		//地図表示領域のリサイズ
		inst.oOutParentOffset = new VMPoint(20,20);
		inst.elemOut.style.width = inst.oOutSize.width - inst.oOutParentOffset.x * 2 + "px";
		inst.elemOut.style.height = inst.oOutSize.height - inst.oOutParentOffset.y * 2 + "px";
		inst.elemOut.style.top = inst.oOutParentOffset.y + "px";
		inst.elemOut.style.left = inst.oOutParentOffset.x + "px";
		var w = VMCommon.getNumber(inst.elemOut.style.width);
		var h = VMCommon.getNumber(inst.elemOut.style.height);
		inst.changeOutSize( new VMSize(w,h));
		this.resize(inst);
		
		//コンテナの中に追加
		inst.container.appendChild(this.elemTopArrow);
		inst.container.appendChild(this.elemLeftArrow);
		inst.container.appendChild(this.elemRightArrow);
		inst.container.appendChild(this.elemBottomArrow);

	},
 	//-----------------------------------------------------//
	// メソッド名（非公開）：resize
	// 引数：inst - VMapインスタンス
	// 戻り値：なし
	// 機能：地図の状態に合わせてコントロールをリサイズする
	//-----------------------------------------------------//
	resize: function(inst){

		this.elemTopArrow.style.left = "0px"; 
		this.elemTopArrow.style.top = "0px";
		this.elemTopArrow.style.width = (inst.oOutParentOffset.x * 2 + inst.oOutSize.width) + "px"; 
		this.elemTopArrow.style.height = "20px";
		this.elemArrow1.style.left = "0px";
		this.elemArrow1.style.top = "0px";
		this.elemArrow2.style.left = (inst.oOutSize.width / 2 + inst.oOutParentOffset.x) + "px";
		this.elemArrow2.style.top = "0px";
		this.elemArrow3.style.left = (inst.oOutSize.width + inst.oOutParentOffset.x) + "px";
		this.elemArrow3.style.top = "0px";

		this.elemLeftArrow.style.left = "0px";
		this.elemLeftArrow.style.top = "20px";
		this.elemLeftArrow.style.width = "20px"; 
		this.elemLeftArrow.style.height = inst.oOutSize.height + "px";
		this.elemArrow4.style.left = "0px";
		this.elemArrow4.style.top = (inst.oOutSize.height / 2 - inst.oOutParentOffset.y / 2) + "px"

		this.elemRightArrow.style.left = (inst.oOutSize.width + inst.oOutParentOffset.x) + "px";
		this.elemRightArrow.style.top = "20px";
		this.elemRightArrow.style.width = "20px"; 
		this.elemRightArrow.style.height = inst.oOutSize.height + "px";
		this.elemArrow5.style.left = "0px";
		this.elemArrow5.style.top = (inst.oOutSize.height / 2 - inst.oOutParentOffset.y / 2) + "px";

		this.elemBottomArrow.style.left = "0px"; 
		this.elemBottomArrow.style.top = (inst.oOutSize.height  + inst.oOutParentOffset.y) + "px";
		this.elemBottomArrow.style.width = inst.oOutParentOffset.x * 2 + inst.oOutSize.width + "px";
		this.elemBottomArrow.style.height = "20px";
		this.elemArrow6.style.left = "0px";
		this.elemArrow6.style.top = "0px";
		this.elemArrow7.style.left = (inst.oOutSize.width / 2 + inst.oOutParentOffset.x) + "px";
		this.elemArrow7.style.top = "0px";
		this.elemArrow8.style.left = (inst.oOutSize.width + inst.oOutParentOffset.x) + "px";
		this.elemArrow8.style.top = "0px";
		
	}
}

//=====================================================//
// VMZoomControlクラス
//=====================================================//
var VMZoomControl = Class.create();
VMZoomControl.prototype = {
	//=====================================================//
	// コンストラクタ
	// 引数：なし
	// 戻り値：VMZoomControlのインスタンス
	// 機能：
	//=====================================================//
	initialize: function(){
		this.typename = "VMZoomControl";
		VMInstances.setInstance(this);
		this.id = "";
		this.elemScale;
		var aImageFile = {
			"1b": VMDefine.ImgDir + "mapl_z1b.gif",
			"2b":VMDefine.ImgDir + "mapl_z2b.gif",
			"3b":VMDefine.ImgDir + "mapl_z3b.gif",
			"4b":VMDefine.ImgDir + "mapl_z4b.gif",
			"5b":VMDefine.ImgDir + "mapl_z5b.gif",
			"6b":VMDefine.ImgDir + "mapl_z6b.gif",
			"7b":VMDefine.ImgDir + "mapl_z7b.gif",
			"8b":VMDefine.ImgDir + "mapl_z8b.gif",
			"9b":VMDefine.ImgDir + "mapl_z9b.gif",
			"10b":VMDefine.ImgDir +"mapl_z10b.gif",
			"11b":VMDefine.ImgDir +"mapl_z11b.gif",
			"12b":VMDefine.ImgDir +"mapl_z12b.gif",
			"1w":VMDefine.ImgDir + "mapl_z1w.gif",
			"2w":VMDefine.ImgDir + "mapl_z2w.gif",
			"3w":VMDefine.ImgDir + "mapl_z3w.gif",
			"4w":VMDefine.ImgDir + "mapl_z4w.gif",
			"5w":VMDefine.ImgDir + "mapl_z5w.gif",
			"6w":VMDefine.ImgDir + "mapl_z6w.gif",
			"7w":VMDefine.ImgDir + "mapl_z7w.gif",
			"8w":VMDefine.ImgDir + "mapl_z8w.gif",
			"9w":VMDefine.ImgDir + "mapl_z9w.gif",
			"10w":VMDefine.ImgDir + "mapl_z10w.gif",
			"11w":VMDefine.ImgDir + "mapl_z11w.gif",
			"12w":VMDefine.ImgDir + "mapl_z12w.gif"
		}
		this.aImgObj = VMCommon.preloadImages(aImageFile);
	},
 	//-----------------------------------------------------//
	// メソッド名（非公開）：removeElem
	// 引数：inst - VMapインスタンス
	// 戻り値：なし
	// 機能：縮尺変更コントロールを無効にする
	//-----------------------------------------------------//
	removeElem : function(inst){
		if(!this.elemScale)Element.remove(this.elemScale);
	},
 	//-----------------------------------------------------//
	// メソッド名（非公開）：createElem
	// 引数：inst - VMapインスタンス
	// 戻り値：なし
	// 機能：縮尺変更コントロールを有効にする
	//-----------------------------------------------------//
	createElem : function(inst){
		this.id = inst.container.id + "_scales";
		this.elemScale = document.createElement("div");
		this.elemScale.id = inst.container.id + "_scale";
		this.elemScale.style.position = "absolute";
		this.elemScale.style.background = "#545454";
		this.elemScale.align = "center";

		this.aryElemImg = new Array();
		//スケールボタン１～１２生成
		for(var i = 1;i <= 12;i++){
            var elemImg = document.createElement('img');
			this.elemScale.appendChild(elemImg);
		}
		//コンテナに追加
		inst.container.appendChild(this.elemScale);
		//ボタンイメージをセット
		this.setButtons(inst);
		//地図表示領域のリサイズ
		inst.elemOut.style.height = inst.oOutSize.height - 26 + "px";
		var w = VMCommon.getNumber(inst.elemOut.style.width);
		var h = VMCommon.getNumber(inst.elemOut.style.height);
		inst.changeOutSize( new VMSize(w,h));

		//コンテナに合わせてサイズ調整
		this.resize(inst);
	},
 	//-----------------------------------------------------//
	// メソッド名（非公開）：resize
	// 引数：inst - VMapインスタンス
	// 戻り値：なし
	// 機能：地図の状態に合わせてコントロールをリサイズする
	//-----------------------------------------------------//
	resize : function(inst){
/*		this.elemScale.style.top = inst.oOutParentOffset.y + inst.oOutSize.height - 26 + "px";
		this.elemScale.style.left = inst.oOutParentOffset.x + "px";
		this.elemScale.style.width = inst.oOutSize.width + "px";
		this.elemScale.style.height = "26px";
		
		//地図表示領域のリサイズ
		inst.elemOut.style.height = inst.oOutSize.height - 26 + "px";
		var w = VMCommon.getNumber(inst.elemOut.style.width);
		var h = VMCommon.getNumber(inst.elemOut.style.height);
		inst.changeOutSize( new VMSize(w,h));
*/
		this.elemScale.style.top = (inst.oOutParentOffset.y * 2) + inst.oOutSize.height + "px";
		this.elemScale.style.left = "0px";
		this.elemScale.style.width = (inst.oOutParentOffset.x * 2) + inst.oOutSize.width + "px";
		this.elemScale.style.height = "26px";
	},
 	//-----------------------------------------------------//
	// メソッド名（非公開）：setLevelBtn
	// 引数：inst - VMapインスタンス
	// 戻り値：なし
	// 機能：現在の縮尺レベルを見てボタンを設定
	//-----------------------------------------------------//
	setButtons: function(inst){
		var oElements = this.elemScale.childNodes;
		for(var i = 0;i < 12;i++){
			var level = i　+　1;
			if(level==inst.getZoom()){
				//現在のスケール
				oElements[i].src = this.aImgObj[level + "w"].src;
			}else{
				oElements[i].src = this.aImgObj[level + "b"].src;
				VMCommon.setAttribute(oElements[i],"onclick","VMEvent.scaleChangeHandler(" + VMInstances.getInstNumber(inst) + "," + VMInstances.getInstNumber(this) + "," + level +")");
			}
			oElements[i].style.margin = "0px";
			oElements[i].style.padding = "0px";
		}
		inst.scaleButtonInst = this;
	}
}

//=====================================================//
// VMLatLngクラス
//=====================================================//
var VMLatLng = Class.create();
VMLatLng.prototype = {
	
	//=====================================================//
	// コンストラクタ
	// 引数：lat_args - 緯度 
	//     lng_args - 経度 
	//　　　緯度経度の形式は次のうちのどれか
	//		1.DPSS(JAFドライブ計画支援システム）
	//			"Ndd.mm.ss.sss"
	//			"Eddd.mm.ss.sss"
	//		2.PADMS（パワーアトラス）
	//			"dd,mm,ss.sss"
	//			"ddd,mm,ss.sss"
	//		3.SEC（１０００ミリ秒）
	//			"123456789"
	//			"123456789"
	// 戻り値：VMLatLngインスタンス
	//=====================================================//
	initialize: function(lat_args, lng_args){
		this.typename = "VMLatLng";
		var dms_type = "";		

		//度分秒配列
		this.aLat = new Array();
		this.aLng = new Array();
		
		//1.DPSS(JAFドライブ計画支援システム）
		//"Ndd.mm.ss.sss"
		//"Eddd.mm.ss.sss"
		this.lat = "";
		this.lng = "";
		var reDPSS_LAT = new RegExp("^N[0-9]{2}\.[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,3}$");
		var reDPSS_LNG = new RegExp("^E[0-9]{3}\.[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,3}$");

		//2.PADMS（パワーアトラス）
		//"dd,mm,ss.sss"
		//"ddd,mm,ss.sss"
		this.lat_padms = "";
		this.lng_padms = "";
		var rePADMS_LAT = new RegExp("^[0-9]{2},[0-9]{1,2},[0-9]{1,2}\.[0-9]{1,3}$");
		var rePADMS_LNG = new RegExp("^[0-9]{3},[0-9]{1,2},[0-9]{1,2}\.[0-9]{1,3}$");

		//3.SEC（１０００ミリ秒）
		//"123456789"
		//"123456789"
		this.lat_sec = "";
		this.lng_sec = "";
		var reSEC_LAT = new RegExp("^[0-9]{8,9}\.*[0-9]*$");
		var reSEC_LNG = new RegExp("^[0-9]{9}\.*[0-9]*$");

		//正規表現でチェックするため文字列に変換
		lat_args = String(lat_args);
		lng_args = String(lng_args);

		if(lat_args.match(reDPSS_LAT) && lng_args.match(reDPSS_LNG)){
			dms_type = "DPSS";
		}else if(lat_args.match(rePADMS_LAT) && lng_args.match(rePADMS_LNG)){
			dms_type = "PADMS";
		}else if(lat_args.match(reSEC_LAT) && lng_args.match(reSEC_LNG)){
			dms_type = "SEC";
		}else{
			alert("VMLatLng 引数のフォーマットが不正です:" + lat_args + "," + lng_args);
			this.typename = "";
			return;
		}
		//各フォーマットに変換して値を保持する
		switch(dms_type){
			case "DPSS":
				this.lat = lat_args;
				this.lng = lng_args;
				//DPSS形式 -> DMS配列
				this.aLat = VMCommon.DPSS_DMStoDMS(this.lat,"LAT");
				this.aLng = VMCommon.DPSS_DMStoDMS(this.lng,"LNG");
				//DMS配列 -> PowerAtrass形式
				this.lat_padms = VMCommon.DMStoPADMS(this.aLat,"LAT");
				this.lng_padms = VMCommon.DMStoPADMS(this.aLng,"LNG");
				//DMS配列 -> 1000ミリ秒
				this.lat_sec = VMCommon.DMStoDMS_SEC(this.aLat,"LAT");
				this.lng_sec = VMCommon.DMStoDMS_SEC(this.aLng,"LNG");
				break;
			case "PADMS":
				this.lat_padms = lat_args;
				this.lng_padms = lng_args;
				//PowerAtrass形式 -> DMS配列
				this.aLat = VMCommon.PADMStoDMS(lat_args);
				this.aLng = VMCommon.PADMStoDMS(lng_args);
				//DMS配列 -> DPSS形式
				this.lat = VMCommon.DMStoDPSS_DMS(this.aLat,"LAT");
				this.lng = VMCommon.DMStoDPSS_DMS(this.aLng,"LNG");
				//DMS配列 -> 1000ミリ秒
				this.lat_sec = VMCommon.DMStoDMS_SEC(this.aLat,"LAT");
				this.lng_sec = VMCommon.DMStoDMS_SEC(this.aLng,"LNG");
				break;
			case "SEC":
				this.lat_sec = parseInt(lat_args);
				this.lng_sec = parseInt(lng_args);
				//1000ミリ秒 -> DMS配列
				this.aLat = VMCommon.DMS_SECtoDMS(parseInt(lat_args));
				this.aLng = VMCommon.DMS_SECtoDMS(parseInt(lng_args));
				//DMS配列 -> DPSS形式
				this.lat = VMCommon.DMStoDPSS_DMS(this.aLat,"LAT");
				this.lng = VMCommon.DMStoDPSS_DMS(this.aLng,"LNG");
				//DMS配列 -> PowerAtrass形式
				this.lat_padms = VMCommon.DMStoPADMS(this.aLat,"LAT");
				this.lng_padms = VMCommon.DMStoPADMS(this.aLng,"LNG");
				break;
		}
		//百分率表記
		this.lat_degree = VMCommon.DMStoDEGREE(this.aLat);
		this.lng_degree = VMCommon.DMStoDEGREE(this.aLng);
	},
	//=====================================================//
	// メソッド名：distanceFrom
	// 引数：other - VMLatLngインスタンス
	// 戻り値：メートル
	// 機能： ２地点間の距離を返す
	//=====================================================//
	distanceFrom : function(other){
		var a = this.lat_degree / 180 * Math.PI;
		var b = this.lng_degree / 180 * Math.PI;
		var c = other.lat_degree / 180 * Math.PI;
		var d = other.lng_degree / 180 * Math.PI;	
		var c1 = Math.cos(a);
		var c2 = Math.cos(c);
		var ac = Math.acos(c1 * Math.cos(b) * c2*Math.cos(d) + Math.sin(b) * c1 * Math.sin(d) * c2 + Math.sin(a) * Math.sin(c));
		var dist = ac * 20000000 / Math.PI;
		return dist;
	}
}
//=====================================================//
// VMSizeクラス
//=====================================================//
var VMSize = Class.create();
VMSize.prototype = {
	//=====================================================//
	// コンストラクタ
	// 引数：width - Number
	//     height - Number
	// 戻り値：VMSizeインスタンス
	//=====================================================//
	initialize: function(width, height){
		this.typename = "VMSize";
		this.width = width;
		this.height = height;
	}
}
//=====================================================//
// VMPointクラス
//=====================================================//
var VMPoint = Class.create();
VMPoint.prototype = {
	//=====================================================//
	// コンストラクタ
	// 引数：x - Number
	//     	 y - Number
	// 戻り値：VMPointインスタンス
	//=====================================================//
	initialize: function(x, y){
		this.typename = "VMPoint";
		this.x = x;
		this.y = y;
	}
}
//────────────────────────────────────────
// VMEvent名前空間／STATICメソッド
//────────────────────────────────────────
var VMEvent = {
	//=====================================================//
	// メソッド名：addEventListener
	// 引数：inst - VMapインスタンス　または VMIconインスタンス
	//     event - click等
	//     handler - function
	// 戻り値：なし
	// 機能：
	//=====================================================//
	addEventListener : function(inst, event, handler){
		if(!inst.typename){
			inst.typename="";
		}
		switch(inst.typename){
		case "VMap":
			Event.observe(inst.elemOut, event, handler, false);
			break;
		case "VMIcon":
			Event.observe(inst.img, event, handler, false);
			//管理配列に登録済みかどうかチェック
			var bMatch = false;
			for(var i=0;i < inst.aEvent.length;i++){
				if(event === inst.aEvent[i] && handler === inst.aEventHandler[i]){
					bMatch = true;
					break;
				}
			}
			//未登録なら管理配列に登録
			if(!bMatch){
				var i = inst.aEvent.length;
				inst.aEvent[i] = event;
				inst.aEventHandler[i] = handler;
			}
			break;
		default:
			Event.observe(inst, event, handler, false);
			break;
		}
	},
	//=====================================================//
	// メソッド名：removeEventListener
	// 引数：inst - VMapインスタンス
	// 戻り値：なし
	// 機能：
	//=====================================================//
	removeEventListener : function(inst, event, handler){
		switch(inst.typename){
		case "VMap":
			Event.stopObserving(inst.elemOut, event, handler, false);
			break;
		case "VMIcon":
			Event.stopObserving(inst.img, event, handler, false);
			//管理配列から削除
			var aBuf1 = new Array();
			var aBuf2 = new Array();
			for(var i=0;i < inst.aEvent.length;i++){
				if(inst === inst.aEvent[i] && handler === inst.aHandlerEvent[i]){
					continue;
				}
				aBuf1.push(inst.aEvent[i]);
				aBuf2.push(inst.aEventHandler[i]);
			}
			inst.aEvent.aEvent = aBuf1;
			inst.aEventHandler = aBuf2;
			break;
		default:
			Event.stopObserving(inst, event, handler, false);
			break;			
		}
	},
	//-----------------------------------------------------//
	// メソッド名（非公開）：addDblClickListener
	// 引数：inst - VMapインスタンス
	// 戻り値：なし
	// 機能：ダブルクリックセンター移動イベント設定
	//-----------------------------------------------------//
	addDblClickListener : function(inst){
		Event.observe(inst.elemOut, 'dblclick', hndDblClickCenter, false);
		// ダブルクリック
		function hndDblClickCenter(e){
			if(inst.isLoaded()==false){
				Event.stop(e);
				return false;
			}
			if(inst.doubleClickCenterEnabled()==false){
				Event.stop(e);
				return false;
			}
		    // 画像表示窓領域div要素の座標を取得
		    var out_point = VMCommon.getWindowOffset(inst.elemOut);
		
		    // ダブルクリック位置と中心の差(移動量)
		    var move_x = e.clientX - out_point.x - (inst.oOutSize.width / 2);
		    var move_y = e.clientY - out_point.y - (inst.oOutSize.height / 2);
	
		    // 移動[スクロール]実行
		    scroll_Point(move_x,move_y);

			//スケール１、２、３はスクロールのみで抜ける
			if(inst.nScaleLevel >= 1 && inst.nScaleLevel <= 3){
				return;
			}

			//画像格納領域div内かどうかチェック
			if(inst.endCheck()==false){
				//既読タイル管理配列初期化
				inst.aLoadedTiles = new Array();
				//中心点設定更新
				inst.calcCenter();
				//画像格納領域 - 削除・再作成
				inst.createElemImgBuf();
				//全タイルロード
			    inst.loadImage(inst.oImgBufPos.x, inst.oImgBufPos.y);
				//バブリングとデフォルトイベントアクションの停止
				Event.stop(e);
				return false;
			}
				
		    // タイルに画像をロードする
		    var x = inst.oImgBufPos.x;
		    var y = inst.oImgBufPos.y;
		    inst.loadImage(x, y);
	
		    // バブリングとデフォルトイベントアクションの停止
			Event.stop(e);
		    return false;

		}
		// ダブルクリック用地図スクロール
		function scroll_Point(mv_x, mv_y){
		    // 座標の絶対値が1以下であれば中断
		    if((Math.abs(mv_x) < 1) && (Math.abs(mv_y) < 1)){
		        return;
		    }
		    var x = inst.oImgBufPos.x - mv_x;
		    var y = inst.oImgBufPos.y - mv_y;
		    inst.elemImgBuf.style.left = x + 'px';
		    inst.elemImgBuf.style.top  = y  + 'px';
		    inst.oImgBufPos.x = x;
		    inst.oImgBufPos.y = y;
		}
	},
	//-----------------------------------------------------//
	// メソッド名（非公開）：addDraggingListener
	// 引数：inst - VMapインスタンス
	// 戻り値：なし
	// 機能：地図ドラッグイベント設定
	//-----------------------------------------------------//
	addDraggingListener : function(inst){
		Event.observe(inst.elemOut, 'mousedown', hndDragStart, false);

		//ドラッグ開始
		function hndDragStart(e){
			if (inst.isLoaded() == false) {
				Event.stop(e);
				return false;
			}
			if (inst.draggingEnabled() == false) {
				Event.stop(e);
				return false;
			}
			// 画像表示窓領域div要素の座標を取得
			inst.oOutPos = VMCommon.getWindowOffset(inst.elemOut);
			
			// 画像格納領域div要素の座標を取得
			var point = VMCommon.getWindowOffset(inst.elemImgBuf);
			// 画像格納領域div要素とマウスポインターの位置の差分を求める
			inst.nLeft_dif = e.clientX - point.x;
			inst.nTop_dif = e.clientY - point.y;
			
			//ドキュメント全体にイベントリスナーをセット
			Event.observe(document, 'mousemove', moveElem, false);
			Event.observe(document, 'mouseup', dragEnd, false);
			//バブリングとデフォルトイベントアクションの停止
			Event.stop(e);
			return false;
		}
		//ドラッグ終了
		function dragEnd(e){
			Event.stopObserving(document, 'mousemove', moveElem, false);
			Event.stopObserving(document, 'mouseup', dragEnd, false);
			//バブリングとデフォルトイベントアクションの停止
			Event.stop(e);
			return false;
		}
		//ドラッグ中
		function moveElem(e){
			//マウスがブラウザー表示領域から外れたら終了
			if ((navigator.appName == 'Netscape' && navigator.userAgent.indexOf("Safari") < 0) ||
			navigator.userAgent.indexOf("Opera") >= 0) {
				if (e.clientX >= window.innerWidth - 20 || e.clientX <= 10 ||
				e.clientY >= window.innerHeight - 30 ||
				e.clientY <= 10) {
					dragEnd(e);
					return false;
				}
			}
			//TODO: 画像格納領域div内かどうかチェック
//			if(inst.endCheck()==false){
//				dragEnd(e);
//				return false;
//			}
			
			//画像格納領域移動
			var x = e.clientX - inst.oOutPos.x - inst.nLeft_dif;
			var y = e.clientY - inst.oOutPos.y - inst.nTop_dif;
			inst.elemImgBuf.style.left = x + 'px';
			inst.elemImgBuf.style.top = y + 'px';
			inst.oImgBufPos.x = x;
			inst.oImgBufPos.y = y;
			//画像ロード
			inst.loadImage(x, y);
			//バブリングとデフォルトイベントアクションの停止
			Event.stop(e);
			return false;
		}
	},
	//-----------------------------------------------------//
	// メソッド名（非公開）：addIconDraggingListener
	// 引数： map - VMapインスタンス
	//        icon - VMIconインスタンス
	// 戻り値：なし
	// 機能：アイコンドラッグイベント設定
	//-----------------------------------------------------//
	addIconDraggingListener : function(map,icon){
		Event.observe(icon.elemIcon, 'mousedown', hndIconDragStart, false);
		//ドラッグ開始
		function hndIconDragStart(e){
			if (icon.draggingEnabled() == false) {
				Event.stop(e);
				return false;
			}
			// 罫線削除
			if(icon.oInfo!=null){
				icon.oInfo.clearLine();
			}
			//ドキュメント全体にイベントリスナーをセット
			Event.observe(document, 'mousemove', moveElem, false);
			Event.observe(document, 'mouseup', dragEnd, false);
			//バブリングとデフォルトイベントアクションの停止
			Event.stop(e);
			return false;

			//ドラッグ終了
			function dragEnd(e){
				Event.stopObserving(document, 'mousemove', moveElem, false);
				Event.stopObserving(document, 'mouseup', dragEnd, false);

				// 罫線描画
				if(icon.oInfo!=null){
					icon.oInfo.drawLine();
				}
				
				//緯度経度更新
				icon.latlng = VMCommon.POINTtoLatLng(map,icon.point);
				
				//バブリングとデフォルトイベントアクションの停止
				Event.stop(e);
				return false;
			}
			//ドラッグ中
			function moveElem(e){
				//マウスがブラウザー表示領域から外れたら終了
				if ((navigator.appName == 'Netscape' && navigator.userAgent.indexOf("Safari") < 0) ||
				navigator.userAgent.indexOf("Opera") >= 0) {
					if (e.clientX >= window.innerWidth - 20 || e.clientX <= 10 ||
					e.clientY >= window.innerHeight - 30 ||
					e.clientY <= 10) {
						dragEnd(e);
						return false;
					}
				}
				icon.point = VMCommon.getOnMapOffset(map,Event.pointerX(e),Event.pointerY(e));
				//地図上のWIN座標→imgBuf上のWIN座標へ変換
				icon.point.x = (-icon.map.oImgBufPos.x) + icon.point.x;
				icon.point.y = (-icon.map.oImgBufPos.y) + icon.point.y;
				
				//アイコン移動
				icon.elemIcon.style.top = icon.point.y - icon.iconAnchor.y + "px";
				icon.elemIcon.style.left = icon.point.x - icon.iconAnchor.x + "px";

				//バブリングとデフォルトイベントアクションの停止
				Event.stop(e);
				return false;
			}
		}
	},
	//-----------------------------------------------------//
	// メソッド名（非公開）：addInfoWinDraggingListener
	// 引数： map - VMapインスタンス
	//      info - VMInfoインスタンス
	//		icon - VMIconインスタンス
	// 戻り値：なし
	// 機能：アイコンドラッグイベント設定
	//-----------------------------------------------------//
	addInfoWinDraggingListener : function(info){
		Event.observe(info.elemInfoWin, 'mousedown', VMEvent.startInfoDrag.bindAsEventListener(info), false);
	},
	//ドラッグ開始
	startInfoDrag : function(e){ 
		var info = this;
		if (info.draggingEnabled() == false) {
			Event.stop(e);
			return false;
		}
		//罫線削除
		info.clearLine();

		/*--------------------*/
		//contentsの内容をチェック
		/*--------------------*/
		//contentsにフォームやコントロールが含まれている場合、infowindowがmouseupイベント（ドラッグ終了）を検知できない不具合が起こる。
		//マウスポインタがフォームオブジェクトにあるときにはすべてのイベントは、そのオブジェクトによって認識されるため。 
		//contentsにフォームやコントロールが含まれていたらinfowindowのドラッグ処理を終了するイベントを設定する
		info.endfunc = VMEvent.endInfoDrag.bind(info);
		var oTextareaElems = this.elemInfoWin.getElementsByTagName("textarea");
		for(var i=0;i < oTextareaElems.length;i++){
			Event.observe(oTextareaElems.item(i), 'scroll', info.endfunc, false);
			Event.observe(oTextareaElems.item(i), 'mousedown', info.endfunc, false);
		}
		var oInputElems = this.elemInfoWin.getElementsByTagName("input");
		for(var i=0;i < oInputElems.length;i++){
			Event.observe(oInputElems.item(i), 'mousedown', info.endfunc, false);
		}

		//噴出し上の座標
		var elem = Event.element(e);
		while(elem.id!=info.id){
			elem = elem.parentNode;
			if(!elem){
				alert("error");
				break;//error
			}
		}		
		var click_pos = VMCommon.getOnElemOffset(elem,Event.pointerX(e),Event.pointerY(e));

		//ドキュメント全体にイベントリスナーをセット
		info.moveInfoDrag = 	VMEvent.moveInfoDrag.bindAsEventListener(info,click_pos);
		Event.observe(document, 'mousemove',info.moveInfoDrag , false);
		info.endInfoDrag = VMEvent.endInfoDrag.bindAsEventListener(info);
		Event.observe(document, 'mouseup',info.endInfoDrag , false);
		VMEvent.info = info;
		
		//バブリングとデフォルトイベントアクションの停止
		Event.stop(e);
		return false;
	},
	//ドラッグ中
	moveInfoDrag : function(e,click_pos){
		var info = this;
		//マウスがブラウザー表示領域から外れたら終了
		if ((navigator.appName == 'Netscape' && navigator.userAgent.indexOf("Safari") < 0) ||
		navigator.userAgent.indexOf("Opera") >= 0) {
			if (e.clientX >= window.innerWidth - 20 || e.clientX <= 10 ||
			e.clientY >= window.innerHeight - 30 ||
			e.clientY <= 10) {
				func = VMEvent.endInfoDrag.bind(info);
				func(e);
				return false;
			}
		}
		
		//アイコンコンテナ上の座標
		var point = VMCommon.getOnElemOffset(info.icon.elemIcon,Event.pointerX(e),Event.pointerY(e));
		
		info.elemInfoWin.top = point.y - click_pos.y;
		info.elemInfoWin.left = point.x - click_pos.x;

		//移動
		info.elemInfoWin.style.top =  info.elemInfoWin.top + "px";
		info.elemInfoWin.style.left = info.elemInfoWin.left + "px";

		//バブリングとデフォルトイベントアクションの停止
		Event.stop(e);
		return false;
	},
	//ドラッグ終了
	endInfoDrag : function(e){
		var info = this;
		Event.stopObserving(document, 'mousemove',info.moveInfoDrag , false);
		Event.stopObserving(document, 'mouseup',info.endInfoDrag , false);


		/**2008/5/29 start**/
		// 画像表示窓領域div要素の座標を取得
	    var out_pos = VMCommon.getWindowOffset(info.map.elemOut);
	    var p1 = VMCommon.getWindowOffset(info.elemInfoWin);				//左上
	    var p2 = new VMPoint(p1.x + info.size.width, p1.y + info.size.height);	//右下
		//マウスが地図表示領域から外れたら
		if (p2.x >= (out_pos.x + info.map.oOutSize.width)){
			//移動
			info.elemInfoWin.left = info.elemInfoWin.left - (p2.x - (out_pos.x + info.map.oOutSize.width));
			info.elemInfoWin.style.left = info.elemInfoWin.left + "px";	
		} 
		if(p1.x <= out_pos.x){
			//移動
			info.elemInfoWin.left = info.elemInfoWin.left + (out_pos.x - p1.x);
			info.elemInfoWin.style.left = info.elemInfoWin.left + "px";		
		}
		if(p1.y <= out_pos.y){
			//移動
			info.elemInfoWin.top = info.elemInfoWin.top + (out_pos.y - p1.y);
			info.elemInfoWin.style.top = info.elemInfoWin.top + "px";				
		}
		if(p2.y >= (out_pos.y + info.map.oOutSize.height)) {
			//移動
			info.elemInfoWin.top = info.elemInfoWin.top - (p2.y - (out_pos.y + info.map.oOutSize.height));
			info.elemInfoWin.style.top = info.elemInfoWin.top + "px";				
		}
		/**2008/5/29 end**/


		var oTextareaElems = this.elemInfoWin.getElementsByTagName("textarea");
		for(var i=0;i < oTextareaElems.length;i++){
			Event.stopObserving(oTextareaElems.item(i), 'scroll', info.endfunc, false);
			Event.stopObserving(oTextareaElems.item(i), 'mousedown', info.endfunc, false);
		}
		var oInputElems = this.elemInfoWin.getElementsByTagName("input");
		for(var i=0;i < oInputElems.length;i++){
			Event.stopObserving(oInputElems.item(i), 'mousedown', info.endfunc, false);
		}
 
		// 罫線描画
		info.drawLine();
		//バブリングとデフォルトイベントアクションの停止
		Event.stop(e);
		return false;
	},
	//-----------------------------------------------------//
	// メソッド名（非公開）：scaleChangeHandler
	// 引数： instNum1 - 地図インスタンス
	//      instNum2 - 縮尺コントロールインスタンス
	//      level - 縮尺レベル
	// 戻り値：なし
	// 機能：縮尺ボタンクリックイベントハンドラ
	//-----------------------------------------------------//
	scaleChangeHandler:function(instNum1,instNum2,level){
		var map = VMInstances.getInstance(instNum1);
		map.setZoom(level);//ボタン選択状態への切り替えはsetZoom内で行うよう変更
//		var cntrl = VMInstances.getInstance(instNum2);
//		cntrl.setButtons(map);
	},
	//-----------------------------------------------------//
	// メソッド名（非公開）：directionChangeHandler
	// 引数： instNum1 - 地図インスタンス
	//      instNum2 - 方向移動コントロールインスタンス
	//      dirction - 方向コード
	// 戻り値：なし
	// 機能：方向移動ボタンクリックイベントハンドラ
	//-----------------------------------------------------//
	directionChangeHandler:function(instNum1,instNum2,dirction){
		var map = VMInstances.getInstance(instNum1);
		map.setMapMoving(dirction);
//		var cntrl = VMInstances.getInstance(instNum2);
	},
	//-----------------------------------------------------//
	// メソッド名（非公開）：disableAddIcon
	// 引数：なし
	// 戻り値：なし
	// 機能：アイコン追加可に設定。イベント処理回避用
	//-----------------------------------------------------//
	bAddIconEnabled : true,
	disableAddIcon : function(){
		VMEvent.bAddIconEnabled = false;
	},
	//-----------------------------------------------------//
	// メソッド名（非公開）：addIcon
	// 引数：icon - VMIconオブジェクト
	// 戻り値：なし
	// 機能：アイコン追加不可に設定。イベント処理回避用
	//-----------------------------------------------------//
	enableAddIcon : function(){
		VMEvent.bAddIconEnabled = true;
	},
	//=====================================================//
	// メソッド名（非公開）：addIconEnabled
	// 引数：icon - VMIconオブジェクト
	// 戻り値：なし
	// 機能：アイコン追加可否設定取得。イベント処理回避用
	//=====================================================//
	addIconEnabled : function(){
		return 	VMEvent.bAddIconEnabled;
	}
}


//────────────────────────────────────────
// VMInstances名前空間／STATICメソッド（非公開）
//────────────────────────────────────────
var VMInstances = {
	//-----------------------------------------------------//
	// （非公開） インスタンス管理配列
	//-----------------------------------------------------//
	ary: new Array(),
	//-----------------------------------------------------//
	// メソッド名（非公開）：segInstance
	// 引数：inst - インスタンス参照
	// 戻り値：なし
	// 機能：インスタンスを登録
	//-----------------------------------------------------//
	setInstance: function(inst){
		VMInstances.ary.push(inst);
	},
	//-----------------------------------------------------//
	// メソッド名（非公開）：getInstNumber
	// 引数：inst - インスタンス参照
	// 戻り値：なし
	// 機能：インスタンスの登録番号取得
	//-----------------------------------------------------//
	getInstNumber: function(inst){
		for (var i = 0; i < VMInstances.ary.length; i++) {
			if (VMInstances.ary[i] == inst) {
				return i;
			}
		}
	},
	//-----------------------------------------------------//
	// メソッド名（非公開）：getInstance
	// 引数：instNum - インスタンス登録番号
	// 戻り値：inst - インスタンス参照
	// 機能：インスタンス取得
	//-----------------------------------------------------//
	getInstance: function(instNum){
		return VMInstances.ary[instNum];
	}
}
//────────────────────────────────────────
// VMCommon名前空間／STATICメソッド
//────────────────────────────────────────
var VMCommon = {
	lat_per_pix: {
		0:"",1:"",2:"",3:"",4:"",5:"",6:"",7:"",8:"",9:"",10:"",11:""
	},
	lng_per_pix : {
		0:"",1:"",2:"",3:"",4:"",5:"",6:"",7:"",8:"",9:"",10:"",11:""
	},
	//=====================================================//
	// メソッド名：ajaxGetData
	// 引数：url - cgiのURL
	//     params - パラメータ
	//     complete - 成功時のハンドラ
	//     failure - 失敗時のハンドラ
	//     exeption - 例外時のハンドラ
	//     asynch - true:非同期, false:同期
	// 戻り値：なし
	// 機能： Ajaxリクエスト
	//=====================================================//
	ajaxGetData: function(url, params, complete, failure, exeption, asynch) {
		var option = {
			method: 'get',
			parameters: params,
			onComplete : complete,
			onFailure : failure,
			onException : exeption,
			asynchronous : asynch
		};
		new Ajax.Request(url, option);
	},
	//=====================================================//
	// メソッド名：ajaxPostData
	// 引数：url - cgiのURL
	//     params - パラメータ
	//     complete - 成功時のハンドラ
	//     failure - 失敗時のハンドラ
	//     exeption - 例外時のハンドラ
	//     asynch - true:非同期, false:同期
	// 戻り値：なし
	// 機能： Ajaxリクエスト
	//=====================================================//
	ajaxPostData : function(url, params, complete, failure, exeption,asynch) {
		var option = {
			method: 'post',
			postBody : params,
			onComplete : complete,
			onFailure : failure,
			onException : exeption,
			asynchronous : asynch			
		};
		new Ajax.Request(url, option);
	},
	failure : function(request){
		alert("failure: " + request.responseText);
	},
	exeption : function(request){
		alert("exeption: " + request.responseText)
	},
	//=====================================================//
	// メソッド名：PADMStoDMS
	// 引数：PADMS - PowerAtrasDMS "135,23,52.720"
	// 戻り値： array(d,m,s)
	// 機能： PowerAtrasDMS -> DMS配列
	//=====================================================//
    PADMStoDMS : function (PADMS){
        var a = PADMS.split(/,/g);
        var aDMS = new Array();
        aDMS["D"]=a[0];
        aDMS["M"]=VMCommon.zeroPadding(a[1],2,"left");
        var aS = a[2].split(".");	//08.370
		aDMS["S"] = VMCommon.zeroPadding(aS[0],2,"left") + "." + VMCommon.zeroPadding(aS[1],3,"right");
        return aDMS;
	},
	//=====================================================//
	// メソッド名：DMStoPADMS
	// 引数：aDMS - 度分秒
	//     TYPE - "LAT" or "LNG" 
	// 戻り値："dd,mm,ss.sss"
	// 機能： DMS配列 -> PowerAtrasDMS
	//=====================================================//
    DMStoPADMS : function(aDMS, TYPE){
		var PADMS="";
		if(TYPE=="LAT"){
			PADMS += VMCommon.zeroPadding(aDMS["D"],2,"left") + ",";
		}else{
			PADMS += VMCommon.zeroPadding(aDMS["D"],3,"left") + ",";
		}
		PADMS += VMCommon.zeroPadding(aDMS["M"],2,"left") + ",";
		var a = aDMS["S"].split(".");
		PADMS += VMCommon.zeroPadding(a[0],2,"left");
		if(a.length>1){
			PADMS += "." + VMCommon.zeroPadding(a[1],3,"right");
		}else{
			PADMS += ".000";
		}
        return PADMS;
	},
	//=====================================================//
	// メソッド名：DMStoDPSS_DMS
	// 引数：aDMS - 度分秒配列
	//     TYPE - "LAT" or "LNG" 
	// 戻り値："Ndd.mm.ss.sss" "Eddd.mm.ss.sss"
	// 機能： DMS配列 -> DPSS形式に変換
	//=====================================================//
	DMStoDPSS_DMS : function(aDMS, TYPE){
		var DPSS_DMS="";
		if(TYPE=="LAT"){
			DPSS_DMS = "N"
			DPSS_DMS += VMCommon.zeroPadding(aDMS["D"],2,"left") + ".";
		}else{
			DPSS_DMS = "E";
			DPSS_DMS += VMCommon.zeroPadding(aDMS["D"],3,"left") + ".";
		}
		DPSS_DMS += VMCommon.zeroPadding(aDMS["M"],2,"left") + ".";
		var a = aDMS["S"].split(".");
		DPSS_DMS += VMCommon.zeroPadding(a[0],2,"left");
		if(a.length>1){
			DPSS_DMS += "." + VMCommon.zeroPadding(a[1],3,"right");
		}else{
			DPSS_DMS += ".000";
		}
		return DPSS_DMS;
	},
	//=====================================================//
	// メソッド名：DPSS_DMStoDMS
	// 引数：DPSS_DMS - "Ndd.mm.ss.sss" "Eddd.mm.ss.sss"
	//     TYPE - "LAT" or "LNG" 
	// 戻り値：aDMS
	// 機能： DPSS形式に変換 -> DMS配列
	//=====================================================//
	DPSS_DMStoDMS : function(DPSS_DMS, TYPE){
		DPSS_DMS = DPSS_DMS.replace("N", "");    // 頭のNを削除
		DPSS_DMS = DPSS_DMS.replace("E", "");    // 頭のEを削除
		var a = DPSS_DMS.split(".");
		var aDMS = new Array();
		if(TYPE=="LAT"){
			aDMS["D"]=VMCommon.zeroPadding(a[0],2,"left");		
		}else{
			aDMS["D"]=VMCommon.zeroPadding(a[0],3,"left");		
		}
		aDMS["M"]=VMCommon.zeroPadding(a[1],2,"left");
		aDMS["S"]=VMCommon.zeroPadding(a[2],2,"left") + "." + VMCommon.zeroPadding(a[3],3,"right");
		return aDMS;
	},
	//=====================================================//
	// メソッド名：DMStoDMS_SEC
	// 引数： aDMS - 度分秒配列
	// 戻り値：千ミリ秒
	// 機能： DMS配列 -> 千ミリ秒
	//=====================================================//
    DMStoDMS_SEC : function(aDMS){
        var DMS_SEC = (aDMS["D"] * 3600) + (aDMS["M"] * 60) + parseFloat(aDMS["S"]);
		DMS_SEC = DMS_SEC * 1000;
		DMS_SEC = parseInt(DMS_SEC);
        return DMS_SEC;
	},
	//=====================================================//
	// メソッド名：DMS_SECtoDMS
	// 引数：DMS_SEC - 千ミリ秒
	// 戻り値：度分秒
	// 機能： 千ミリ秒　-> DMS配列
	//=====================================================//
    DMS_SECtoDMS : function(DMS_SEC){
    	DMS_SEC = DMS_SEC / 1000;
    	var aDMS = new Array();
        aDMS["D"] = Math.floor(DMS_SEC / 3600);
        aDMS["M"] = Math.floor((DMS_SEC % 3600) / 60);
        aDMS["S"] = DMS_SEC - (aDMS["D"]*3600) - (aDMS["M"]*60);
		var s = String(aDMS["S"]);
        var aS = s.split(".");	//08.370
        if(aS.length<2){
        	aS[1] = "000";
        }
		aDMS["S"] = VMCommon.zeroPadding(aS[0],2,"left") + "." + aS[1].substr(0,3);
 		return aDMS;
	},
	//=====================================================//
	// メソッド名：DMStoDEGREE
	// 引数：aDMS - 度分秒配列
	// 戻り値：百分率表記
	// 機能： DMS配列 -> 百分率表記
	//=====================================================//
	DMStoDEGREE : function(aDMS){
		//百分率表記 ＝ 度 ＋ (分／60) ＋ (秒／3600)
		var d = parseInt(aDMS["D"]);
		var m = parseInt(aDMS["M"]);
		var s = parseFloat(aDMS["S"]);
		return d + m / 60 + s / 3600;
	},
	//=====================================================//
	// メソッド名：DEGREEtoDMS
	// 引数：DEGREE - 百分率表記
	// 戻り値：aDMS - 度分秒配列
	// 機能： 百分率表記 -> DMS配列 
	//=====================================================//
	DEGREEtoDMS : function(DEGREE){		
		var sf = Math.round(DEGREE * 360000);
		var s = Math.floor(sf / 100) % 60;
		var m = Math.floor(sf / 6000) % 60;
		var d = Math.floor(sf / 360000);
		sf %= 100;
		if(m < 10) m = "0" + m;
		if(s < 10) s = "0" + s;
		if(sf < 10) sf = "0" + sf;
    	var aDMS = new Array();
		aDMS["D"] = d;		
		aDMS["M"] = m;
		aDMS["S"] = s;
		return aDMS;
	},
	//=====================================================//
	// メソッド名：setAttribute
	// 引数：elem - element参照
	//		 event - "onclick"等
	//		 handler - 
	// 戻り値：なし
	// 機能：element属性設定。IEのsetAttributeバグ回避
	//=====================================================//
	setAttribute : function(elem,event,handler){
		if(navigator.appName=="Microsoft Internet Explorer"){
			elem.setAttribute(event, new Function(handler));
		}else{
			elem.setAttribute(event, handler);
		}
	},
	//=====================================================//
	// メソッド名：getDocumentOffset
	// 引数：elem - element参照
	// 戻り値：VMPointインスタンス
	// 機能：document上のオフセット取得
	//=====================================================//
	getDocumentOffset : function(elem) {
	    var oPos = new VMPoint();
	    oPos.x = elem.offsetLeft;
	    oPos.y = elem.offsetTop;
	    while(elem.offsetParent) {
	       elem = elem.offsetParent;
	       oPos.x += elem.offsetLeft;
	       oPos.y += elem.offsetTop;
	    }
	    return oPos;
	},
	//=====================================================//
	// メソッド名：getWindowOffset
	// 引数：elem - element参照
	// 戻り値：VMPointインスタンス
	// 機能：画面上のオフセット取得
	//     （docオフセットからスクロールを差し引いたオフセット）
	//=====================================================//
	getWindowOffset : function(elem){
		var oPos = VMCommon.getDocumentOffset(elem);
		var scrolllOffset = String(Position.realOffset(elem));
		var aScroll = scrolllOffset.split(",");
	    oPos.x = oPos.x - aScroll[0];
	    oPos.y = oPos.y - aScroll[1];
	    return oPos;
	},
	//=====================================================//
	// メソッド名：getOnMapOffset
	// 引数：inst - VMapインスタンス参照
	//       pointerX  -  Event.pointerX(e)
	//       pointerY  -  Event.pointerY(e)
	// 戻り値：VMPointインスタンス
	// 機能：地図上のオフセット取得
	//=====================================================//
	getOnMapOffset : function(inst,pointerX,pointerY){
		var out_point = VMCommon.getDocumentOffset(inst.elemOut);
		var x = pointerX - out_point.x;
		var y = pointerY - out_point.y;
		return new VMPoint(x,y);
	},
	//=====================================================//
	// メソッド名：getOnElemOffset
	// 引数：elem - element参照
	//       pointerX  -  Event.pointerX(e)
	//       pointerY  -  Event.pointerY(e)
	// 戻り値：VMPointインスタンス
	// 機能：イベントが発生したエレメント上のオフセット取得
	//=====================================================//
	getOnElemOffset : function(elem,pointerX,pointerY){
	    var out_point = VMCommon.getDocumentOffset(elem);
		var x = pointerX - out_point.x;
		var y = pointerY - out_point.y;
		return new VMPoint(x,y);		   
	},
	//=====================================================//
	// メソッド名：preloadImages
	// 引数：fileNameAry - 連想配列
	// 戻り値：imageAry - 連想配列
	// 機能：イメージ先読み
	//=====================================================//
	preloadImages : function(fileNameAry){
		var imageAry = new Array();
		var oImg;
		for(key in fileNameAry){
//			alert(key + ":" + fileNameAry[key]);
		    imageAry[key] = new Image();
		    imageAry[key].src = fileNameAry[key];
		}
		return imageAry;
	},
	//=====================================================//
	// メソッド名：zeroPadding
	// 引数：num - 値
	//     keta - ゼロパディングする桁数
	//     kbn - "left" or "right" ゼロ埋めする方向
	// 戻り値：val - 
	// 機能：イメージ先読み
	//=====================================================//
	zeroPadding : function(num,keta,kbn){
		var val = String(num);
		if(val.length >= keta)return num;
		cnt = keta - val.length;
		for(var i=0;i < cnt;i++){
			if(kbn=="left"){
				val = "0" + val;
			}else if(kbn=="right"){
				val = val + "0";
			}
		}
		return val;
	},
	//=====================================================//
	// メソッド名：POINTtoLatLng
	// 引数：map - VMapインスタンス
	//     point - VMPointインスタンス　地図の左上を0とするWIN座標
	// 戻り値：VMLatLngインスタンス
	// 機能：WIN座標 -> 物理座標
	//=====================================================//
	POINTtoLatLng : function(map,point){
		var leftTop = map.getLeftTopLatLng();
		var lat_sec = leftTop.lat_sec - (point.y * map.lat_per_pix);
		var lng_sec = leftTop.lng_sec + (point.x * map.lng_per_pix);
		return new VMLatLng(lat_sec,lng_sec);
	},
	//=====================================================//
	// メソッド名：LatLngtoPOINT
	// 引数：map - VMapインスタンス
	//     latlng - VMLatLngインスタンス
	// 戻り値：VMPointインスタンス　地図の左上を0とするWIN座標
	// 機能： 物理座標 -> WIN座標
	//=====================================================//
	LatLngtoPOINT : function(map,latlng){
		var leftTop = map.getLeftTopLatLng();
		var lat_sec_diff = leftTop.lat_sec - latlng.lat_sec;
		var lng_sec_diff = latlng.lng_sec - leftTop.lng_sec;
		var y =	lat_sec_diff / map.lat_per_pix;
		var x = lng_sec_diff / map.lng_per_pix;
		//小数点四捨五入　2008/5/26 add
		x = Math.round(x);
		y = Math.round(y);
		return new VMPoint(x,y);
	},
	//=====================================================//
	// メソッド名：setUnselectable
	// 引数：elem - Element
	// 戻り値： なし
	// 機能： 要素を選択不可に設定する
	//=====================================================//
	setUnselectable : function(elem){
		elem.unselectable = "on";
		Element.setStyle(elem, {
			"-moz-user-select": "none",
			"-khtml-user-select": "none",
			"user-select": "none"
		});
	},
	//=====================================================//
	// メソッド名：getNumber
	// 引数：str - styleのサイズ文字列 ex. "100pix"
	// 戻り値： なし
	// 機能： styleのサイズ文字列から"pix"を除いた数字を返す
	//=====================================================//
	getNumber : function(str){
		var ret = "";
		for(var i = 0; i < str.length;i++){
			if(str.charAt(i).match(/[0-9]/)){
				ret += str.charAt(i);
			}
		}
		return Number(ret);
	}
}
