package com.zcxk.common;

import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;

public class ConvertXY {
	
	private static double a = 0, e2, e1, C0, C1, C2, C3, Ro0, Ro2;

	public ConvertXY() {
		a = 6378245.0;

		e2 = 0.00669342162297;
		e1 = 0.00673852541468;

		C0 = 6367558.49686;
		C1 = 32005.79642;
		C2 = 133.86115;
		C3 = 0.7031;
		Ro0 = 180 / 3.1415926535897932;
		Ro2 = 3600 * Ro0;
	}

	private MyPoint JWtoXY(WTDFM J, WTDFM W, double Lo) {
		double L, B, T, ng2, N, Mo, X0, X1, X2, X3, X4, X5, X6, X7, X8;
		L = J.m_DEGREE;// 计算°数
		B = W.m_RADIAN;// 计算弧°已将°数转换为弧°
		T = Math.tan(B);
		ng2 = e1 * Math.pow(Math.cos(B), 2.0);
		N = a / Math.pow((1.0 - e2 * Math.pow(Math.sin(B), 2.0)), (1.0 / 2.0));
		Mo = (L - Lo) * Math.cos(B) / Ro0;
		X0 = C0 * B
				- Math.cos(B) * (C1 * Math.sin(B) + C2 * Math.pow(Math.sin(B), 3.0) + C3 * Math.pow(Math.sin(B), 5.0));
		X1 = N * Mo;
		X2 = C0 * B;
		X3 = Math.cos(B) * (C1 * Math.sin(B) + C2 * Math.pow(Math.sin(B), 3.0) + C3 * Math.pow(Math.sin(B), 5.0));
		X4 = N * T * Math.pow(Mo, 2.0) / 2.0;
		X5 = (5.0 - Math.pow(T, 2.0) + 9.0 * ng2 + 4.0 * Math.pow(ng2, 2.0)) * N * T * Math.pow(Mo, 4.0) / 24.0;
		X6 = (61.0 - 58.0 * Math.pow(T, 2.0) + Math.pow(T, 4.0)) * N * T * Math.pow(Mo, 6.0) / 720.0;
		X7 = (1.0 - Math.pow(T, 2.0) + ng2) * N * Math.pow(Mo, 3.0) / 6.0;
		X8 = (5.0 - 18.0 * Math.pow(T, 2.0) + Math.pow(T, 4.0) + 14.0 * ng2 - 58.0 * ng2 * Math.pow(T, 2.0)) * N
				* Math.pow(Mo, 5.0) / 120.0;
		double dblX = X2 - X3 + X4 + X5 + X6;// 计算式
		double dblY = X1 + X7 + X8;// +500000.0;//计算式
		MyPoint pPoint = new MyPoint();
		pPoint.Y = (int) (dblX) + (int) ((dblX - (int) (dblX)) * 1000.0) / 1000.0;
		pPoint.X = (int) (dblY) + (int) ((dblY - (int) (dblY)) * 1000.0) / 1000.0 + 500000.0;
		return pPoint;
	}

	public MyPoint Convert(String x, String y) {
		WTDFM J = new WTDFM();
		WTDFM W = new WTDFM();
		J.m_DEGREE = Double.valueOf(x);
		W.m_DEGREE = Double.valueOf(y);
		J.DEGtoDFM();
		W.DEGtoDFM();
		// 中央子午线
		MyPoint pPoint = JWtoXY(J, W, 116.3502518055556);
		// pPoint.X = pPoint.X - 400000;
		// Y坐标偏移
		pPoint.Y = pPoint.Y - 4114702.5;
		// 坐标校正
		// X - 50
		// Y - 32
		pPoint.X = pPoint.X - 50;
		pPoint.Y = pPoint.Y - 32;
		return pPoint;
	}

	/* 经纬度转西安80坐标 */
	public static MyPoint ConvertXYToXian80(String x, String y,String moveXY) {
		MyPoint pPoint = new MyPoint();
		double dblLon = Double.parseDouble(x), dblLat = Double.parseDouble(y);
		if(dblLon <= 0 && dblLat <= 0){
			pPoint.X = 0;
			pPoint.Y = 0;
		}else{
			StringBuilder dblX80 = new StringBuilder();
			StringBuilder dblY80 = new StringBuilder();
			ICoordinate pCoordinate = CoordinateFactory.CreateCoordinate(Spheroid.Xian80);
			pCoordinate.GaussPrjCalculate(dblLon, dblLat, dblX80, dblY80);
			double X80 = Double.parseDouble(String.format("%.4f", Double.parseDouble(dblX80.toString())));
			double Y80 = Double.parseDouble(String.format("%.4f", Double.parseDouble(dblY80.toString())));
			X80 += -196600;
			Y80 += 270;
			int moveX=0,moveY=0;
			if(!StringUtils.isEmpty(moveXY)){
				moveX=Integer.parseInt(moveXY.split(",")[0]);
				moveY=Integer.parseInt(moveXY.split(",")[1]);
			}
			pPoint.X = X80+moveX;
			pPoint.Y = Y80+moveY;
		}
		return pPoint;
	}

	/* 经纬度转墨卡托投影坐标 */
	public static MyPoint ConvertXYToMercato(String x, String y,String moveXY) {
		MyPoint mercator = new MyPoint();
		if(Double.parseDouble(x) <= 0 && Double.parseDouble(y) <= 0){
			mercator.X = 0;
			mercator.Y = 0;
		}else{
			double dblLon = Double.parseDouble(x) * 20037508.34 / 180;
			double dblLat = Math.log(Math.tan((90 + Double.parseDouble(y)) * Math.PI / 360)) / (Math.PI / 180);
			dblLat = dblLat * 20037508.34 / 180;
			int moveX=0,moveY=0;
			if(!StringUtils.isEmpty(moveXY)){
				moveX=Integer.parseInt(moveXY.split(",")[0]);
				moveY=Integer.parseInt(moveXY.split(",")[1]);
			}
			mercator.X = dblLon+moveX;
			mercator.Y = dblLat+moveY;
		}
		return mercator;
	}


	/**
	 * 西安80坐标转经纬度
	 *
	 * @param x
	 * @param y
	 * @return
	 */
	public static MyPoint ConvertXian80ToXY(String x, String y,String moveXY) {
		MyPoint pPoint = new MyPoint();
		if(Double.parseDouble(x) <= 0 && Double.parseDouble(y) <= 0){
			pPoint.X =0;
			pPoint.Y =0;
		}else{
			double dx = Double.parseDouble(x)+196600, dy = Double.parseDouble(y)-270;
			int moveX=0,moveY=0;
			if(!StringUtils.isEmpty(moveXY)){
				moveX=Integer.parseInt(moveXY.split(",")[0]);
				moveY=Integer.parseInt(moveXY.split(",")[1]);
			}
			dx -= moveX;
			dy -= moveY;
			StringBuilder dblLon = new StringBuilder();
			StringBuilder dblLat = new StringBuilder();
			ICoordinate pCoordinate = CoordinateFactory.CreateCoordinate(Spheroid.WGS84);
			pCoordinate.GaussPrjInvCalculate(dx, dy, dblLon, dblLat);
			double X84 = Double.parseDouble(String.format("%.6f", Double.parseDouble(dblLon.toString())));
			double Y84 = Double.parseDouble(String.format("%.6f", Double.parseDouble(dblLat.toString())));

			pPoint.X =X84;
			pPoint.Y =Y84;
		}
		return pPoint;
	}

	// 墨卡托转经纬度
	public static MyPoint MercatorToXY(String x, String y,String moveXY) {
		MyPoint lngLat = new MyPoint();
		double lng = Double.parseDouble(x);
		double lat = Double.parseDouble(y);
		if(lng<=0 && lat<=0){
			lngLat.X=0;
			lngLat.Y=0;
		}else{
			int moveX=0,moveY=0;
			if(!StringUtils.isEmpty(moveXY)){
				moveX=Integer.parseInt(moveXY.split(",")[0]);
				moveY=Integer.parseInt(moveXY.split(",")[1]);
			}
			lng -= moveX;
			lat -= moveY;
			lngLat.X = lng / 20037508.34 * 180;
			double mmy = lat / 20037508.34 * 180;
			lngLat.Y = 180 / Math.PI * (2 * Math.atan(Math.exp(mmy * Math.PI / 180)) - Math.PI / 2);
		}
		return lngLat;
	}


	public static void main(String[] args) {

		//String password = MD5Util.md5Encode("a83c71250a7363ea492aed2640d402ef");
		//System.out.println(password);
		//93.011981,43.601386
		ConvertXY convert = new ConvertXY();//93.024905,43.597244
		MyPoint pt = convert.ConvertXYToMercato("93.024905", "43.597244",null);
		//pt = convert.LonlatToMercator("93.011981", "43.601386");
		BigDecimal bdX= new BigDecimal(pt.X);
		BigDecimal bdY= new BigDecimal(pt.Y);
		
		System.out.println("latitude,longtitude:" + String.valueOf(bdX.toPlainString()) + "," + String.valueOf(bdY.toPlainString()));
		
//		 pt = convert.LonlatToMercator("121.398804", "29.944973");
//			
//		 bdX= new BigDecimal(pt.X);
//		 bdY= new BigDecimal(pt.Y);
//			
//	     System.out.println("latitude,longtitude:" + String.valueOf(bdX.toPlainString()) + "," + String.valueOf(bdY.toPlainString()));
//
//			
//	     pt = convert.LonlatToMercator("121.746342", "29.823072");
//				
//		bdX= new BigDecimal(pt.X);
//	    bdY= new BigDecimal(pt.Y);
//				
//		 System.out.println("latitude,longtitude:" + String.valueOf(bdX.toPlainString()) + "," + String.valueOf(bdY.toPlainString()));

	}

}
