WGS84地理坐标系和CGCS2000坐标相互转换

1.以下位代码直接调用就可以,中央子午线需要查看网址经纬度中央子午线对照表。需要geotools和opengis和kotlin需要的jar包。下载链接:https://pan.baidu.com/s/1AZnt3YHk9CyofYdvgLRaHQ 
提取码:ak47 
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package org.fh.controller.fhoa;

import cn.hutool.core.lang.Tuple;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.junit.Test;
import org.opengis.geometry.MismatchedDimensionException;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import kotlin.jvm.internal.Intrinsics;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.constraints.NotNull;
import java.awt.geom.Point2D;
import java.util.Date;
/**
 * @Description  84坐标转china2000
 * @Author 未知人员
 * @Date 2021/8/27 11:21 
 * @Param 
 * @return 
 **/
@Controller
@RequestMapping(value="/Geo")
public class Geo {

    private  double p = 206264.80624709636D;
    /**WGS84地理坐标系转换成CGCS2000坐标
     * @throws Exception
     */
    @RequestMapping(value="/list")
    @ResponseBody
    public  double [] xytolatlon() {
        double lat ,lon;
        double Y=612508.8925;//平面坐标Y
        double X=4998860.4083;//平面坐标X
        double L0=123D;//中央子午线,结合这个网址进行查找,目前用的EPSG:4532中的123D。https://wenku.baidu.com/view/e219e246e3bd960590c69ec3d5bbfd0a7856d530.html
        Y-=500000;
        double []  result  = new double[2];
        double iPI = 0.0174532925199433;//pi/180
        double a = 6378137.0; //长半轴 m
        double b = 6356752.31414; //短半轴 m
        double f = 1/298.257222101;//扁率 a-b/a
        double e = 0.0818191910428; //第一偏心率 Math.sqrt(5)
        double ee = Math.sqrt(a*a-b*b)/b; //第二偏心率
        double bf = 0; //底点纬度
        double a0 = 1+(3*e*e/4) + (45*e*e*e*e/64) + (175*e*e*e*e*e*e/256) + (11025*e*e*e*e*e*e*e*e/16384) + (43659*e*e*e*e*e*e*e*e*e*e/65536);
        double b0 = X/(a*(1-e*e)*a0);
        double c1 = 3*e*e/8 +3*e*e*e*e/16 + 213*e*e*e*e*e*e/2048 + 255*e*e*e*e*e*e*e*e/4096;
        double c2 = 21*e*e*e*e/256 + 21*e*e*e*e*e*e/256 + 533*e*e*e*e*e*e*e*e/8192;
        double c3 = 151*e*e*e*e*e*e*e*e/6144 + 151*e*e*e*e*e*e*e*e/4096;
        double c4 = 1097*e*e*e*e*e*e*e*e/131072;
        bf = b0 + c1*Math.sin(2*b0) + c2*Math.sin(4*b0) +c3*Math.sin(6*b0) + c4*Math.sin(8*b0); // bf =b0+c1*sin2b0 + c2*sin4b0 + c3*sin6b0 +c4*sin8b0 +...
        double tf = Math.tan(bf);
        double n2 = ee*ee*Math.cos(bf)*Math.cos(bf); //第二偏心率平方成bf余弦平方
        double c = a*a/b;
        double v=Math.sqrt(1+ ee*ee*Math.cos(bf)*Math.cos(bf));
        double mf = c/(v*v*v); //子午圈半径
        double nf = c/v;//卯酉圈半径

        //纬度计算
        lat=bf-(tf/(2*mf)*Y)*(Y/nf) * (1-1/12*(5+3*tf*tf+n2-9*n2*tf*tf)*(Y*Y/(nf*nf))+1/360*(61+90*tf*tf+45*tf*tf*tf*tf)*(Y*Y*Y*Y/(nf*nf*nf*nf)));
        //经度偏差
        lon=1/(nf*Math.cos(bf))*Y -(1/(6*nf*nf*nf*Math.cos(bf)))*(1+2*tf*tf +n2)*Y*Y*Y + (1/(120*nf*nf*nf*nf*nf*Math.cos(bf)))*(5+28*tf*tf+24*tf*tf*tf*tf)*Y*Y*Y*Y*Y;
        result[0] =retain6(lat/iPI);
        result[1] =retain6(L0+lon/iPI);
        System.out.println(result[1]+","+result[0]);
        //GetXY(result[0],result[1],6.0D);
        return result;
    }
    private  double retain6(double num) {
        String result = String.format("%.10f", num);//小数点后面保留10位小数
        return Double.valueOf(result);
    }

    /**
     * CGCS2000坐标转换成WGS84地理坐标系
     * @param x纬度
     * @param y经度
     */
    public  void xyTowgs84(double x,double y) {
        double L0 = gaussLongToDegreen(x, y, 6);
        double a = 6378137.0D;
        double efang = 0.0066943799901413D;
        double e2fang = 0.0067394967422764D;
        y = y - (double)500000;
        double m0 = 0.0D;
        double m2 = 0.0D;
        double m4 = 0.0D;
        double m6 = 0.0D;
        double m8 = 0.0D;
        m0 = a * ((double)1 - efang);
        m2 = 1.5D * efang * m0;
        m4 = efang * m2 * 5.0D / 4.0D;
        m6 = efang * m4 * 7.0D / 6.0D;
        m8 = efang * m6 * 9.0D / 8.0D;
        double a0 = 0.0D;
        double a2 = 0.0D;
        double a4 = 0.0D;
        double a6 = 0.0D;
        double a8 = 0.0D;
        a0 = m0 + m2 / 2.0D + m4 * 3.0D / 8.0D + m6 * 5.0D / 16.0D + m8 * 35.0D / 128.0D;
        a2 = m2 / 2.0D + m4 / 2.0D + m6 * 15.0D / 32.0D + m8 * 7.0D / 16.0D;
        a4 = m4 / 8.0D + m6 * 3.0D / 16.0D + m8 * 7.0D / 32.0D;
        a6 = m6 / 32.0D + m8 / 16.0D;
        a8 = m8 / 128.0D;
        double FBf = 0.0D;
        double Bf0 = x / a0;

        for(double Bf1 = 0.0D; Bf0 - Bf1 >= 1.0E-4D; Bf0 = (x - FBf) / a0) {
            Bf1 = Bf0;
            FBf = -a2 * Math.sin((double)2 * Bf0) / (double)2 + a4 * Math.sin((double)4 * Bf0) / (double)4 - a6 * Math.sin((double)6 * Bf0) / (double)6 + a8 * Math.sin((double)8 * Bf0) / (double)8;
        }

        double Wf = Math.sqrt((double)1 - efang * Math.sin(Bf0) * Math.sin(Bf0));
        double Nf = a / Wf;
        double Mf = a * ((double)1 - efang) / Math.pow(Wf, 3.0D);
        double nffang = e2fang * Math.cos(Bf0) * Math.cos(Bf0);
        double tf = Math.tan(Bf0);
        double B = Bf0 - tf * y * y / ((double)2 * Mf * Nf) + tf * ((double)5 + (double)3 * tf * tf + nffang - (double)9 * nffang * tf * tf) * Math.pow(y, 4.0D) / ((double)24 * Mf * Math.pow(Nf, 3.0D)) - tf * ((double)61 + (double)90 * tf * tf + (double)45 * Math.pow(tf, 4.0D)) * Math.pow(y, 6.0D) / ((double)720 * Mf * Math.pow(Nf, 5.0D));
        double l = y / (Nf * Math.cos(Bf0)) - ((double)1 + (double)2 * tf * tf + nffang) * Math.pow(y, 3.0D) / ((double)6 * Math.pow(Nf, 3.0D) * Math.cos(Bf0)) + ((double)5 + (double)28 * tf * tf + (double)24 * Math.pow(tf, 4.0D)) * Math.pow(y, 5.0D) / ((double)120 * Math.pow(Nf, 5.0D) * Math.cos(Bf0));
        double L = l + L0;
        double[] array_B = this.rad2dms(B);
        double[] array_L = this.rad2dms(L);
        double Bdec = this.dms2dec(array_B);
        double Ldec = this.dms2dec(array_L);
        System.out.println(Bdec+":"+Ldec);
        //return new Tuple(Bdec, Ldec);
    }
    public  double gaussLongToDegreen(double B, double L, int N) {
        double L00 = (double)Math.round(L / (double)3) * (double)3;
        return L00 / (double)180 * 3.1415926D;
    }

    public  double[] rad2dms(double rad) {
        double[] a = new double[]{0.0D, 0.0D, 0.0D};
        double dms = rad * p;
        a[0] = Math.floor(dms / 3600.0D);
        a[1] = Math.floor((dms - a[0] * (double)3600) / 60.0D);
        a[2] = (double)((int)Math.floor(dms - a[0] * (double)3600)) - a[1] * (double)60;
        return a;
    }

    public  double dms2dec( double[] dms) {
        Intrinsics.checkNotNullParameter(dms, "dms");
        double dec = 0.0D;
        dec = dms[0] + dms[1] / 60.0D + dms[2] / 3600.0D;
        return dec;
    }
}