/*********************************************************************
*	All Rights reserved,Copyright(c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JKUejbZahyo
*	ソースファイル名：JKUejbZahyo.java
*	作成者			：富士通
*	日付			：2011年07月20日
*＜機能概要＞
*	座標系変換計算部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2011/07/20	FJ）		新規作成
*
**********************************************************************/
package eo.common.util;


import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.LinkedHashMap;

import eo.common.constant.JKUStrConst;

/**
 *  <dd>クラス名：座標系変換計算
 *  <dd>クラス説明：座標系変換計算部品です。
 *  <dd>備考：
 * @version  1.01 2011/07/22
 * @author 富士通
 *
 */
public class JKUZahyo
{
	/** 円周率 */
	private static final BigDecimal M_PI = new BigDecimal("3.14159265358979323846");
	
	/** map用X座標 */
	private static final String ZAHYO_MAP_X = JKUStrConst.ZAHYO_MAP_X;
	
	/** map用Y座標 */
	private static final String ZAHYO_MAP_Y = JKUStrConst.ZAHYO_MAP_Y;
	
	/** map用6系X座標 */
	private static final String ZAHYO_MAP_X_6 = JKUStrConst.ZAHYO_MAP_X_6;
	
	/** map用6系Y座標 */
	private static final String ZAHYO_MAP_Y_6 = JKUStrConst.ZAHYO_MAP_Y_6;
	
	/** map用5系X座標 */
	private static final String ZAHYO_MAP_X_5 = JKUStrConst.ZAHYO_MAP_X_5;
	
	/** map用5系Y座標 */
	private static final String ZAHYO_MAP_Y_5 = JKUStrConst.ZAHYO_MAP_Y_5;
	
	/** mapエラー格納箇所 */
	private static final String ZAHYO_SET_ERROR = JKUStrConst.ZAHYO_SET_ERROR;
	
	/**
	 * エラー値
	 */
	
	/** mapエラー:公共座標系エラー */
	private static final String ZAHYO_MAP_ERROR_NO = JKUStrConst.ZAHYO_MAP_ERROR_NO;
	
	/** mapエラー:座標値の範囲エラー */
	private static final String ZAHYO_MAP_ERROR_RANGE = JKUStrConst.ZAHYO_MAP_ERROR_RANGE;
	
	/** mapエラー:オーバーフローエラー */
	private static final String ZAHYO_MAP_ERROR_OVER = JKUStrConst.ZAHYO_MAP_ERROR_OVER;
	
	/** mapエラー:その他エラー */
	private static final String ZAHYO_MAP_ERROR_OTHER = JKUStrConst.ZAHYO_MAP_ERROR_OTHER;
	
	/** mapエラー:nullエラー */
	private static final String ZAHYO_MAP_ERROR_NULL = JKUStrConst.ZAHYO_MAP_ERROR_NULL;
	
	/** 近畿圏経度・最大値 比較用 */
	private static final long MAX_COL_KDO = 136550000L;
	
	/** 近畿圏経度・最小値 比較用 */
	private static final long MIN_COL_KDO = 134200000L;
	
	/** 近畿圏緯度・最大値 比較用 */
	private static final long MAX_COL_IDO = 36000000L;
	
	/** 近畿圏緯度・最小値 比較用 */
	private static final long MIN_COL_IDO = 33300000L;
	
	/** 日本の総延長3000km(3000000m)から各系からの距離100000000mとして最大値 */
	private static final long JAPAN_CHECK_MAX = 1000000000L;
	
	/** 日本の総延長3000km(3000000m)から各系からの距離100000000mとして最小値 */
	private static final long JAPAN_CHECK_MIN = -1000000000L;
	
	/** 浮動小数点を用いない比較を行うための桁数消去に用いる */
	private static final BigDecimal MULTIPLE_ITME = new BigDecimal("1000000");
	
	/** 赤道半径 ベッセル（TOKYO） */
	private static final BigDecimal TOKYO_DATUM_EQUATORIAL_LENGTH = new BigDecimal("6377397.155");
	
	/** 扁平率（分母値） ベッセル（TOKYO） */
	private static final BigDecimal TOKYO_DATUM_FLATTEND_VALUE = new BigDecimal("299.152813");
	
	/** 赤道半径 測地成果2000（WGS84） */
	private static final BigDecimal WGS84_DATYN_EQUATORIAL_LENGTH = new BigDecimal("6378137.0");
	
	/** 扁平率（分母値） 測地成果2000（WGS84） */
	private static final BigDecimal WGS84_DATUM_FLATTEND_VALUE = new BigDecimal("298.257222101");
	
	/** 緯度経度データ座標系指示コード */
	private static final int TOKYO_DATUM = 0;
	
	/** 緯度経度データ座標系指示コード */
//	private static final int WGS84_DATUM = 1;
	
	// 各種アルゴリズムは、国土地理院のサイトにある内容を参照
	// http://vldb.gsi.go.jp/sokuchi/surveycalc
	// 下記モジュール内の x,y について、国土地理院サイトのアルゴリズム記載の x,y と扱いが異なる。
	// xが経度方向(東:+/西:-)、yが緯度方向(北:+、南:-)の数学的座標系である。
	
	/** 長半径、扁平率を保持 */
	private static final BigDecimal[][] ELLIPSEVALUE = 
	{
		{ TOKYO_DATUM_EQUATORIAL_LENGTH , TOKYO_DATUM_FLATTEND_VALUE },
		{ WGS84_DATYN_EQUATORIAL_LENGTH , WGS84_DATUM_FLATTEND_VALUE }
	};
	
	/** 座標系原点 */
	private static final double[] SYSTEM = 
	{
		0,	0,
		33,	129 + (double)30 / 60,
		33,	131,
		36,	132	+ (double)10 / 60,
		33,	133	+ (double)30 / 60,
		36,	134	+ (double)20 / 60,
		36,	136,
		36,	137	+ (double)10 / 60,
		36,	138	+ (double)30 / 60,
		36,	139	+ (double)50 / 60,
		40,	140	+ (double)50 / 60,
		44,	140	+ (double)15 / 60,
		44,	142	+ (double)15 / 60,
		44,	144	+ (double)15 / 60,
		26,	142,
		26,	127	+ (double)30 / 60,
		26,	124,
		26,	131,
		20,	136,
		26,	154
	};
	
	/**
	 * 
	 *  <dd>メソッド名：卯酉線曲率半径計算
	 *  <dd>メソッド説明：卯酉線曲率半径を求める計算。
	 *  <dd>備考：
	 * @param lat 緯度
	 * @param er  赤道半径 ベッセル（TOKYO）
	 * @param e1  第一離心率
	 * @return pv 卯酉線曲率半径
	 */
	private static double calN(double lat , double er , double e1)
	{
		double pv = 0;
		double local_w = 0;
		local_w = Math.sqrt(1 - Math.pow(e1 * Math.sin(lat) , 2));
		pv = er / local_w;
		
		return pv;
	}
	
	/**
	 * 
	 *  <dd>メソッド名：第一離心率計算
	 *  <dd>メソッド説明：第一離心率を求める計算。
	 *  <dd>備考：
	 * @param td  扁平率（分母値） ベッセル（TOKYO）
	 * @return e1 第一離心率
	 */
	private static double cale1(double td)
	{
		double e1 = 0;
		e1 = Math.sqrt(2 * td - td * td);
		
		return e1;
	}
	
	/**
	 *  <dd>メソッド名：第二離心率計算
	 *  <dd>メソッド説明：第二離心率を求める計算。
	 *  <dd>備考：
	 * @param td  扁平率（分母値） ベッセル（TOKYO）
	 * @return e2 第二離心率
	 */
	private static double cale2(double td)
	{
		double e2 = 0;
		e2 = Math.sqrt(2 / td - 1) / (1 / td - 1);
		
		return e2;
	}
	
	/**
	 * 
	 *  <dd>メソッド名：子午線弧長計算
	 *  <dd>メソッド説明：子午線弧長を求める計算。
	 *  <dd>備考：
	 * @param lat 緯度
	 * @param er  赤道半径 ベッセル（TOKYO）
	 * @param e1  第一離心率
	 * @return me0 子午線弧長
	 */
	private static double b2S(double lat, double er, double e1)
	{
		
		double me0 = 0;
		double[] calItemB = new double[10];
		double[] calItemA = new double[10];
		BigDecimal decCalItem1 = new BigDecimal("4927697775");
		BigDecimal decCalItem2 = new BigDecimal("7516192768");
	
		calItemA[0] = 1 + Math.pow(e1 , 2) * 3 / 4 + Math.pow(e1 , 4) * 45 / 64 + Math.pow(e1 , 6) * 175 / 256 + Math.pow(e1 , 8) * 11025 / 16384
				+ Math.pow(e1 , 10) * 43659 / 65536 + Math.pow(e1 , 12) * 693693 / 1048576
				+ Math.pow(e1 , 14) * 19324305 / 29360128 + Math.pow(e1 , 16) * decCalItem1.divide(decCalItem2).doubleValue();
		calItemA[1] = Math.pow(e1 , 2) * 3 / 4 + Math.pow(e1 , 4) * 15 / 16 + Math.pow(e1 , 6) * 525 / 512 + Math.pow(e1 , 8) * 2205 / 2048
				+ Math.pow(e1 , 10) * 72765 / 65536 + Math.pow(e1 , 12) * 297297 / 262144
				+ Math.pow(e1 , 14) * 135270135 / 117440512 + Math.pow(e1 , 16) * 547521975 / 469762048;
		calItemA[2] = Math.pow(e1 , 4) * 15 / 64 + Math.pow(e1 , 6) * 105 / 256 + Math.pow(e1 , 8) * 2205 / 4096
				+ Math.pow(e1 , 10) * 10395 / 16384 + Math.pow(e1 , 12) * 1486485 / 2097152
				+ Math.pow(e1 , 14) * 45090045 / 58720256 + Math.pow(e1 , 16) * 766530765 / 939524096;
		calItemA[3] = Math.pow(e1 , 6) * 35 / 512 + Math.pow(e1 , 8) * 315 / 2048
				+ Math.pow(e1 , 10) * 31185 / 131072 + Math.pow(e1 , 12) * 165165 / 524288
				+ Math.pow(e1 , 14) * 45090045 / 117440512 + Math.pow(e1 , 16) * 209053845 / 469762048;
		calItemA[4] = Math.pow(e1 , 8) * 315 / 16384 + Math.pow(e1 , 10) * 3465 / 65536 + Math.pow(e1 , 12) * 99099 / 1048576
				+ Math.pow(e1 , 14) * 4099095 / 29360128 + Math.pow(e1 , 16) * 348423075 / 1879048192;
		calItemA[5] = Math.pow(e1 , 10) * 693 / 131072 + Math.pow(e1 , 12) * 9009 / 524288
				+ Math.pow(e1 , 14) * 4099095 / 117440512 + Math.pow(e1 , 16) * 26801775 / 469762048;
		calItemA[6] = Math.pow(e1 , 12) * 3003 / 2097152
				+ Math.pow(e1 , 14) * 315315 / 58720256 + Math.pow(e1 , 16) * 11486475 / 939524096;
		calItemA[7] = Math.pow(e1 , 14) * 45045 / 117440512 + Math.pow(e1 , 16) * 765765 / 469762048;
		calItemA[8] = Math.pow(e1 , 16) * 765765 / decCalItem2.doubleValue();
		
		calItemB[0] = er * (1 - Math.pow(e1 , 2)) * calItemA[0];
		calItemB[1] = er * (1 - Math.pow(e1 , 2)) * (-calItemA[1] / 2);
		calItemB[2] = er * (1 - Math.pow(e1 , 2)) * (calItemA[2] / 4);
		calItemB[3] = er * (1 - Math.pow(e1 , 2)) * (-calItemA[3] / 6);
		calItemB[4] = er * (1 - Math.pow(e1 , 2)) * (calItemA[4] / 8);
		calItemB[5] = er * (1 - Math.pow(e1 , 2)) * (-calItemA[5] / 10);
		calItemB[6] = er * (1 - Math.pow(e1 , 2)) * (calItemA[6] / 12);
		calItemB[7] = er * (1 - Math.pow(e1 , 2)) * (-calItemA[7] / 14);
		calItemB[8] = er * (1 - Math.pow(e1 , 2)) * (calItemA[8] / 16);
		
		me0 = calItemB[0] * lat + calItemB[1] * Math.sin(2 * lat) + calItemB[2] * Math.sin(4 * lat)
				+ calItemB[3] * Math.sin(6 * lat) + calItemB[4] * Math.sin(8 * lat)
				+ calItemB[5] * Math.sin(10 * lat) + calItemB[6] * Math.sin(12 * lat)
				+ calItemB[7] * Math.sin(14 * lat) + calItemB[8] * Math.sin(16 * lat);
		
		return me0;
	}
	

	
	/**
	 * 
	 *  <dd>メソッド名：平面直角座標および子午線収差角計算
	 *  <dd>メソッド説明：緯度・経度から平面直角座標および子午線収差角を求める計算。
	 *  <dd>備考：
	 * @param lat  緯度
	 * @param lon  経度
	 * @param cdX  平面直角座標（Ｘ）横方向
	 * @param cdY  平面直角座標（Ｙ）縦方向
	 * @param lon0 座標系原点の経度
	 * @param m0   縮尺係数
	 * @param me0  赤道から原点までの子午線弧長
	 * @param eqme 緯度を用いて計算した子午線弧長
	 * @param pv   卯酉線曲率半径
	 * @param e2   第二離心率
	 * @return zahyo 公共座標
	 */
	private static LinkedHashMap<String, BigDecimal> bl2XY(double lat, double lon, double cdX, double cdY, double lon0, 
				double m0, double me0, double eqme, double pv, double e2)
	{
		LinkedHashMap<String, BigDecimal> zahyo = new LinkedHashMap<String, BigDecimal>();
		double p11 = 0;
		double[] p2 = new double[7];
		double[] p3 = new double[5];
		double resultY = 0;
		double resultX = 0;
		BigDecimal setY = new BigDecimal("0");
		BigDecimal setX = new BigDecimal("0");
		
		p11 = lon - lon0;
		p2[1] = Math.tan(lat);
		p2[2] = Math.pow(p2[1], 2);
		p2[4] = Math.pow(p2[1], 4);
		//
		p2[6] = Math.pow(p2[1], 6);
		p3[2] = Math.pow(e2 * Math.cos(lat), 2);
		p3[4] = Math.pow(p3[2], 2);
		
		resultY = ((eqme - me0) + pv * Math.pow(Math.cos(lat) * p11, 2) * p2[1] / 2
				+ pv * Math.pow(Math.cos(lat) * p11, 4) * p2[1] * (5 - p2[2] + 9 * p3[2] + 4 * p3[4]) / 24
				- pv * Math.pow(Math.cos(lat) * p11, 6) * p2[1] * (-61 + 58 * p2[2] - p2[4] - 270 * p3[2] + 330 * p2[2] * p3[2]) / 720
				- pv * Math.pow(Math.cos(lat) * p11, 8) * p2[1] * (-1385 + 3111 * p2[2] - 543 * p2[4] + p2[6]) / 40320) * m0;
		
		resultX = (pv * Math.cos(lat) * p11
				- pv * Math.pow(Math.cos(lat) * p11, 3) * (-1 + p2[2] - p3[2]) / 6
				- pv * Math.pow(Math.cos(lat) * p11, 5) * (-5 + 18 * p2[2] - p2[4] - 14 * p3[2] + 58 * p2[2] * p3[2]) / 120
				- pv * Math.pow(Math.cos(lat) * p11, 7) * (-6 + +479 * p2[2] - 179 * p2[4] + p2[6]) / 5040) * m0;
		
		setY = new BigDecimal(resultY);
		setX = new BigDecimal(resultX);
		
		zahyo.put(ZAHYO_MAP_Y, setY);
		zahyo.put(ZAHYO_MAP_X, setX);
		
		return zahyo;
	}
	
	
	/**
	 * 
	 *  <dd>メソッド名：公共座標変換計算
	 *  <dd>メソッド説明：公共座標変換の計算。
	 *  <dd>備考：引数で長半径、扁平率指定していたのをモード指定に変更
	 *          ：datum_code
	 *          ：0:日本測地系(TOKYO_DATUM)
	 *          ：1:世界測地系(WGS84_DATUM)
	 * @param lat 緯度
	 * @param lon 経度
	 * @param cdX 平面直角座標（Ｘ）横方向
	 * @param cdY 平面直角座標（Ｙ）縦方向
	 * @param dc  緯度経度データ座標系指示コード
	 * @param cn  座標系番号
	 * @return zahyo 公共座標
	 */
	private static LinkedHashMap<String, BigDecimal> bl2XYFunc(double lat, double lon, double cdX, double cdY, int dc, int cn)
	{
		// 変数の定義
		LinkedHashMap<String, BigDecimal> zahyo = new LinkedHashMap<String, BigDecimal>();
		
		double changelat = 0;
		double changelon = 0;
		double lat0 = 0;
		double lon0 = 0;
		double td = 0;
		double eqme = 0;
		double me0 = 0;
		double pv = 0;
		double e1 = 0;
		double e2 = 0;
		// 縮尺係数
		double m0 = 0.9999;
		BigDecimal er = new BigDecimal("0");
		BigDecimal fi = new BigDecimal("0");
		
		// 引数のチェック
		if(0 > dc || 1 < dc)
		{
			zahyo.put(ZAHYO_MAP_X, new BigDecimal("0"));
			zahyo.put(ZAHYO_MAP_Y, new BigDecimal("0"));
			zahyo.put(ZAHYO_SET_ERROR, new BigDecimal(ZAHYO_MAP_ERROR_OTHER));
			return zahyo;
		}
		if(1 > cn || 19 < cn)
		{
			zahyo.put(ZAHYO_MAP_X, new BigDecimal("0"));
			zahyo.put(ZAHYO_MAP_Y, new BigDecimal("0"));
			zahyo.put(ZAHYO_SET_ERROR, new BigDecimal(ZAHYO_MAP_ERROR_OTHER));
			return zahyo;
		}
		er = ELLIPSEVALUE[dc][0];
		fi = ELLIPSEVALUE[dc][1];
		
	    // 変換元の座標
		changelon = lon * M_PI.doubleValue() / 180;
		changelat = lat * M_PI.doubleValue() / 180;
		
		// 座標系原点の緯度経度
		lat0 = SYSTEM[cn * 2] * M_PI.doubleValue() / 180;
		lon0 = SYSTEM[cn * 2 + 1] * M_PI.doubleValue() / 180;
		
		// 離心率を求める
		td = 1 / fi.doubleValue();
		e1 = cale1(td);
		e2 = cale2(td);
		
		// 赤道から座標系の原点までの子午線弧長
		me0 = b2S(lat0, er.doubleValue(), e1);
		
		// 緯度を与えて赤道からの子午線弧長を求める計算
		eqme = b2S(changelat, er.doubleValue(), e1);
		
		// 卯酉線曲率半径を求める計算
		pv = calN(changelat, er.doubleValue(), e1);
		
		// 座標変換を実行する
		zahyo = bl2XY(changelat, changelon, cdX, cdY, /*lat0,*/ lon0, m0, me0, eqme, pv, /* M,*/ e2);
		
		return zahyo;
	}
	
	/**
	 *  <dd>メソッド名：経緯度の公共座標への変換
	 *  <dd>メソッド説明：経緯度を公共座標に変換する。
	 *  <dd>備考：
	 * @param colNo  座標系番号
	 * @param colKdo 経度
	 * @param colIdo 緯度
	 * @param colX   平面直角座標（Ｘ）横方向
	 * @param colY   平面直角座標（Ｙ）縦方向
	 * @return zahyo 公共座標
	 */
	public static LinkedHashMap<String, BigDecimal> zahyoBX(String colNo,
			String colKdo, String colIdo, String colX, String colY)
	{
		// 返却用map
		LinkedHashMap<String, BigDecimal> zahyo = new LinkedHashMap<String, BigDecimal>();
		
		// 座標系番号
		int col_no = 0;
		// 経度
		double col_kdo = 0;
		// 緯度
		double col_ido = 0;
		// X座標
		double col_X = 0;
		// Y座標
		double col_Y = 0;
		// 経度座標値の範囲チェック(近畿圏)を行うため経度の変換に用いる
		BigDecimal change_kdo = new BigDecimal("0");
		// 緯度座標値の範囲チェック(近畿圏)を行うため緯度の変換に用いる
		BigDecimal change_ido = new BigDecimal("0");
		// 経度座標値の範囲チェック(近畿圏)比較用
		long chk_kdo = 0;
		// 緯度座標値の範囲チェック(近畿圏)比較用
		long chk_ido = 0;
		// 変換結果X座標がオーバーフローしていないかチェックを行うために用いる
		long overCheckX = 0;
		// 変換結果Y座標がオーバーフローしていないかチェックを行うために用いる
		long overCheckY = 0;
		
		// 変換結果X座標
		BigDecimal colX_d = new BigDecimal("0");
		// 変換結果Y座標
		BigDecimal colY_d = new BigDecimal("0");
		
		try
		{
			// 座標系番号nullチェック
			if(null != colNo && !("".equals(colNo)))
			{
				// 座標系番号の変換
				col_no = Integer.parseInt(colNo);
			}
			else
			{
				zahyo.put(ZAHYO_MAP_X, new BigDecimal("0"));
				zahyo.put(ZAHYO_MAP_Y, new BigDecimal("0"));
				zahyo.put(ZAHYO_SET_ERROR, new BigDecimal(ZAHYO_MAP_ERROR_OTHER));
				return zahyo;
			}
			
			// 経度nullチェック
			if(null != colKdo && !("".equals(colKdo)))
			{
				// 経度の変換
				col_kdo = Double.parseDouble(colKdo);
				
				change_kdo = new BigDecimal(col_kdo);
				// 浮動小数点の比較を行わない規約のため
				// 桁数分である1000000倍を行い小数点消去
				change_kdo = change_kdo.multiply(MULTIPLE_ITME);
				// 小数点以下を四捨五入してlong型に
				// BigDecimalでは現行通りの比較式による比較を行えずcompareToによるメソッド比較しか行えない
				// 現行と同じ形の比較を可能な限り行うためlong型に変換
				chk_kdo = change_kdo.setScale(0 , BigDecimal.ROUND_HALF_UP).longValue();
			}
			else
			{
				zahyo.put(ZAHYO_MAP_X, new BigDecimal("0"));
				zahyo.put(ZAHYO_MAP_Y, new BigDecimal("0"));
				zahyo.put(ZAHYO_SET_ERROR, new BigDecimal(ZAHYO_MAP_ERROR_NULL));
				return zahyo;
			}
			
			// 緯度nullチェック
			if(null != colIdo && !("".equals(colIdo)))
			{
				// 緯度の変換
				col_ido = Double.parseDouble(colIdo);
				
				change_ido = new BigDecimal(col_ido);
				// 浮動小数点の比較を行わない規約のため
				// 桁数分である1000000倍を行い小数点消去
				change_ido = change_ido.multiply(MULTIPLE_ITME);
				// 小数点以下を四捨五入してlong型に
				// BigDecimalでは現行通りの比較式による比較を行えずcompareToによるメソッド比較しか行えない
				// 現行と同じ形の比較を可能な限り行うためlong型に変換
				chk_ido = change_ido.setScale(0 , BigDecimal.ROUND_HALF_UP).longValue();
			}
			else
			{
				zahyo.put(ZAHYO_MAP_X, new BigDecimal("0"));
				zahyo.put(ZAHYO_MAP_Y, new BigDecimal("0"));
				zahyo.put(ZAHYO_SET_ERROR, new BigDecimal(ZAHYO_MAP_ERROR_NULL));
				return zahyo;
			}
			
		}
		catch(NumberFormatException e)
		{
			// 変換失敗エラー
			zahyo.put(ZAHYO_MAP_X, new BigDecimal("0"));
			zahyo.put(ZAHYO_MAP_Y, new BigDecimal("0"));
			zahyo.put(ZAHYO_SET_ERROR, new BigDecimal(ZAHYO_MAP_ERROR_OTHER));
			return zahyo;
		}
		
		// 公共座標系のチェック1から15
		if ((1 > col_no) || (15 < col_no))
		{
			// 公共座標系が1から15でない
			zahyo.put(ZAHYO_MAP_X, new BigDecimal("0"));
			zahyo.put(ZAHYO_MAP_Y, new BigDecimal("0"));
			zahyo.put(ZAHYO_SET_ERROR, new BigDecimal(ZAHYO_MAP_ERROR_NO));
			return zahyo;
		}
		
		// 座標値の範囲チェック(近畿圏)
		// 浮動小数点の比較を行わない規約のため浮動小数点は用いない
		if ((MIN_COL_KDO > chk_kdo) || (MAX_COL_KDO < chk_kdo) || (MIN_COL_IDO > chk_ido) || (MAX_COL_IDO < chk_ido))
		{
			zahyo.put(ZAHYO_MAP_X, new BigDecimal("0"));
			zahyo.put(ZAHYO_MAP_Y, new BigDecimal("0"));
			zahyo.put(ZAHYO_SET_ERROR, new BigDecimal(ZAHYO_MAP_ERROR_RANGE));
			return zahyo;
		}
		
		// ------------------------------------
		// 経緯度 −＞ 公共座標 変換計算(6系)を行う
		// ------------------------------------
		zahyo = bl2XYFunc(col_ido, col_kdo, col_X, col_Y, TOKYO_DATUM , col_no);
		
		
		// 処理結果チェック
		if (null != zahyo.get(ZAHYO_SET_ERROR))
		{
			// 処理結果である座標マップのエラー格納値がnullでなかった場合＝公共座標 変換計算内部でエラーが起こっている
			
			// エラーは変換処理内部で設定しているのでそのまま返却すれば良い
			return zahyo;
		}
		
		
		// オーバーフローさせない為のチェック
		// 日本の総延長3000km(3000000m)から各系からの距離100000000mとする
		
		colX_d = zahyo.get(ZAHYO_MAP_X);
		colY_d = zahyo.get(ZAHYO_MAP_Y);
		
		// 比較のため小数点以下を四捨五入しlong型に
		// BigDecimalでは現行通りの比較式による比較を行えずcompareToによるメソッド比較しか行えない
		// 現行と同じ形の比較を可能な限り行うためlong型に変換
		overCheckX = colX_d.setScale(0 , BigDecimal.ROUND_HALF_UP).longValue();
		overCheckY = colY_d.setScale(0 , BigDecimal.ROUND_HALF_UP).longValue();
		
		if ((JAPAN_CHECK_MIN >= overCheckX) || (JAPAN_CHECK_MAX <= overCheckX) ||
				(JAPAN_CHECK_MIN >= overCheckY) || (JAPAN_CHECK_MAX <= overCheckY))
		{
			zahyo.put(ZAHYO_MAP_X, new BigDecimal("0"));
			zahyo.put(ZAHYO_MAP_Y, new BigDecimal("0"));
			zahyo.put(ZAHYO_SET_ERROR, new BigDecimal(ZAHYO_MAP_ERROR_OVER));
			return zahyo;
		}
		
		// 小数点第三位で四捨五入する
		zahyo.put(ZAHYO_MAP_X, colX_d.setScale(2 , RoundingMode.HALF_UP));
		zahyo.put(ZAHYO_MAP_Y, colY_d.setScale(2 , RoundingMode.HALF_UP));
		
		
		return zahyo;
	}
	
	
	
	/**
	 * 5系6系計算を行い結果を一つのmapに格納して返却する
	 * @param colKdo
	 * @param colIdo
	 * @return 
	 */
	public static LinkedHashMap<String, BigDecimal> allZahyoBX(String colKdo, String colIdo)
	{
		
		// 返却用map
		LinkedHashMap<String, BigDecimal> zahyo = new LinkedHashMap<String, BigDecimal>();
		
		// 6系計算用map
		LinkedHashMap<String, BigDecimal> keisan6 = new LinkedHashMap<String, BigDecimal>();
		
		// 5系計算用map
		LinkedHashMap<String, BigDecimal> keisan5 = new LinkedHashMap<String, BigDecimal>();
		
		// 6系計算
		keisan6 = zahyoBX(JKUStrConst.ZAHYO_NO_6, colKdo, colIdo, null, null);
		
		// 5系計算
		keisan5 = zahyoBX(JKUStrConst.ZAHYO_NO_5, colKdo, colIdo, null, null);
		
		// 6系計算結果設定
		zahyo.put(ZAHYO_MAP_X_6, keisan6.get(ZAHYO_MAP_X));
		zahyo.put(ZAHYO_MAP_Y_6, keisan6.get(ZAHYO_MAP_Y));
		// 5系計算結果設定
		zahyo.put(ZAHYO_MAP_X_5, keisan5.get(ZAHYO_MAP_X));
		zahyo.put(ZAHYO_MAP_Y_5, keisan5.get(ZAHYO_MAP_Y));
		
		// 6系エラー設定
		if(null != keisan6.get(ZAHYO_SET_ERROR))
		{
			// エラー格納
			zahyo.put(ZAHYO_SET_ERROR, keisan6.get(ZAHYO_SET_ERROR));
		}
		
		// 5系エラー設定
		if(null != keisan5.get(ZAHYO_SET_ERROR))
		{
			// エラー格納
			zahyo.put(ZAHYO_SET_ERROR, keisan5.get(ZAHYO_SET_ERROR));
		}
		
		return zahyo;
		
	}
	
	
}
