最近项目需要做工程项目在地图的标注,项目的数据是高斯投影坐标,而地图的标注需要用到的是经纬度,因此需要做处理。在网上查找了各种帖子,掉了不少坑,最终完善出了一个工具类,亲测可用,有问题可以提出探讨。

首先是常用坐标系的参数:

(1)北京54坐标系

长半轴(米):6378245.0; 短半轴(米):6356863 ;扁率之倒数:298.3;中央子午线比例系数:1;北向偏离(米):0;东向偏离(米):500000

(2)国家80坐标系

长半轴(米):6378140.0; 短半轴(米):6356755;扁率之倒数:298.25722101;中央子午线比例系数:1;北向偏离(米):0;东向偏离(米):500000

(3)WGS84坐标系

长半轴(米):6378137.0; 短半轴(米):6356755;扁率之倒数:298.257223563;中央子午线比例系数:1;北向偏离(米):0;东向偏离(米):500000

(4)92坐标系(来源于北京54坐标系)

长半轴(米):6378245.0; 短半轴(米):6356863 ;扁率之倒数:298.3;中央子午线比例系数:1;北向偏离(米):2700000;东向偏离(米):400000

@Slf4j
public class GaussBLUtil {

public static void main(String[] args) {
        // 以北京54坐标系为例,其中中央子午线(第3个参数)和偏离参数(第4、5个参数)可根据实际情况调整。第6个参数是长半轴,第7个参数是系数除于扁率
        GaussBLUtil.gaussToBL(2720076.481,  454802.918,118.5,0, 500000,6378245.0,1/ 298.3);
    }

/**
     * @description 高斯投影坐标(平面坐标)转化成经纬度(大地坐标) tip:不带号,直接指定中央经度
     * @param X 平面坐标x
     * @param Y 平面坐标y
     * @param centerL   中央子午线(度)
     * @param X0    北向偏离【米】(X向加常数)
     * @param Y0    东向偏离【米】(Y向加常数)
     * @param factor    卫星椭球坐标投影到平面地图坐标系的投影因子
     * @param param 坐标系参数
     * @date 2023/4/12 15:25
     * @author lyb
     * @return double[]
     */
    public static double[] gaussToBL(double X, double Y, double centerL, double X0, double Y0, double factor, double param){
        int ProjNo;
        // 带宽
        int ZoneWide;
        double[] output = new double[2];
        // latitude0,
        double longitude1, latitude1, longitude0, yval, xval;
        double e1, e2, f, a, ee, NN, T, C, M, D, R, u, fai, iPI;
        //3.1415926535898/180.0;
        iPI = 0.0174532925199433;
        a = factor;// 卫星椭球坐标投影到平面地图坐标系的投影因子
        f = param;// 54年北京坐标系参数
        ZoneWide = 6;

// 中央经线
        longitude0 = centerL * iPI;
        // 带内大地坐标
        log.info("带内大地坐标(偏移前) x={},y={}", X, Y);
        yval = Y-Y0;
        xval = X-X0;
        e2 = 2 * f - f * f;
        e1 = (1.0 - Math.sqrt(1 - e2)) / (1.0 + Math.sqrt(1 - e2));
        ee = e2 / (1 - e2);
        M = xval;
        u = M / (a * (1 - e2 / 4 - 3 * e2 * e2 / 64 - 5 * e2 * e2 * e2 / 256));
        fai = u + (3 * e1 / 2 - 27 * e1 * e1 * e1 / 32) * Math.sin(2 * u) + (21 * e1 * e1 / 16 - 55 * e1 * e1 * e1 * e1 / 32)
                * Math.sin(4 * u) + (151 * e1 * e1 * e1 / 96) * Math.sin(6 * u) + (1097 * e1 * e1 * e1 * e1 / 512) * Math.sin(8 * u);
        C = ee * Math.cos(fai) * Math.cos(fai);
        T = Math.tan(fai) * Math.tan(fai);
        NN = a / Math.sqrt(1.0 - e2 * Math.sin(fai) * Math.sin(fai));
        R = a * (1 - e2) / Math.sqrt((1 - e2 * Math.sin(fai) * Math.sin(fai)) * (1 - e2 * Math.sin
                (fai) * Math.sin(fai)) * (1 - e2 * Math.sin(fai) * Math.sin(fai)));
        D = yval / NN;
        // 计算经度(Longitude) 纬度(Latitude)
        longitude1 = longitude0 + (D - (1 + 2 * T + C) * D * D * D / 6 + (5 - 2 * C + 28 * T - 3 * C * C + 8 * ee + 24 * T * T) * D
                * D * D * D * D / 120) / Math.cos(fai);
        latitude1 = fai - (NN * Math.tan(fai) / R) * (D * D / 2 - (5 + 3 * T + 10 * C - 4 * C * C - 9 * ee) * D * D * D * D / 24
                + (61 + 90 * T + 298 * C + 45 * T * T - 256 * ee - 3 * C * C) * D * D * D * D * D * D / 720);
        // 转换为度 DD
        output[0] = longitude1 / iPI;
        output[1] = latitude1 / iPI;
        log.info("大地坐标L={}度, B={}度", output[0], output[1]);
        return output;
    }

/**
     * @description 由经纬度(大地坐标)转化成高斯投影坐标(平面坐标) tip:不带号,直接指定中央经度
     * @param longitude 经度
     * @param latitude  纬度
     * @param centerL   中央子午线(度)
     * @param X0    北向偏离【米】(X向加常数)
     * @param Y0    东向偏离【米】(Y向加常数)
     * @param factor    卫星椭球坐标投影到平面地图坐标系的投影因子
     * @param param 坐标系参数
     * @date 2023/4/12 11:02
     * @author lyb
     * @return void
     */
    public static double[] bLToGauss(double longitude, double latitude, double centerL, double X0, double Y0, double factor, double param) {
        int ProjNo = 0;
        int ZoneWide; // //带宽
        double[] output = new double[2];
        double longitude1, latitude1, longitude0, xval, yval;
        double a, f, e2, ee, NN, T, C, A, M, iPI;
        iPI = 0.0174532925199433; // //3.1415926535898/180.0;
        ZoneWide = 6; // 6度带宽
        a = factor;
        f = param;
        longitude0 = centerL;
        longitude0 = longitude0 * iPI; // 中央经线
        longitude1 = longitude * iPI; // 经度转换为弧度
        latitude1 = latitude * iPI; // 纬度转换为弧度
        e2 = 2 * f - f * f;
        ee = e2 * (1.0 - e2);
        NN = a/Math.sqrt(1.0 - e2 * Math.sin(latitude1) * Math.sin(latitude1));
        T = Math.tan(latitude1) * Math.tan(latitude1);
        C = ee * Math.cos(latitude1) * Math.cos(latitude1);
        A = (longitude1 - longitude0) * Math.cos(latitude1);
        M = a * ((1 - e2 / 4 - 3 * e2 * e2 / 64 - 5 * e2 * e2 * e2 / 256) * latitude1
                - (3 * e2 / 8 + 3 * e2 * e2 / 32 + 45 * e2 * e2 * e2
                / 1024) * Math.sin(2 * latitude1)
                + (15 * e2 * e2 / 256 + 45 * e2 * e2 * e2 / 1024)
                * Math.sin(4 * latitude1) - (35 * e2 * e2 * e2 / 3072)
                * Math.sin(6 * latitude1));

// 因为是以赤道为Y轴的,与我们南北为Y轴是相反的,所以xy与高斯投影的标准xy正好相反;
        yval = NN * (A + (1 - T + C) * A * A * A / 6 + (5 - 18 * T + T * T + 72 * C - 58 * ee)
                * A * A * A * A * A / 120);
        xval = M + NN
                * Math.tan(latitude1)
                * (A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A / 24 + (61
                - 58 * T + T * T + 600 * C - 330 * ee)
                * A * A * A * A * A * A / 720);
        yval = yval+Y0; xval = xval+X0;
        output[0] = xval;
        output[1] = yval;
        log.info("平面坐标 x={},y={}", output[0], output[1]);
        return output;
    }

}

高斯坐标和经纬度之间的转化相关推荐

  1. 经纬度转高斯坐标 java_经纬度坐标与高斯坐标的转换代码

    /* 功能说明: 将绝对高斯坐标(y,x)转换成绝对的地理坐标(wd,jd).        */ // double y;     输入参数: 高斯坐标的横坐标,以米为单位 // double x; ...

  2. Java各坐标系之间的转换(高斯、WGS84经纬度、Web墨卡托、瓦片坐标)

    本文整理了一些地理坐标系之间的转换(Java代码) pom依赖 <dependency><groupId>com.vividsolutions</groupId>& ...

  3. mysql 计算gps坐标距离_mysql 下 计算 两点 经纬度 之间的距离(转)

    公式如下,单位米: 第一点经纬度:lng1 lat1 第二点经纬度:lng2 lat2 round(6378.138*2*asin(sqrt(pow(sin( (lat1*pi()/180-lat2* ...

  4. 经纬度坐标与高斯坐标的转换代码

    经纬度坐标与高斯坐标的转换代码 /* 功能说明: 将绝对高斯坐标(y,x)转换成绝对的地理坐标(wd,jd).        */ // double y;     输入参数: 高斯坐标的横坐标,以米 ...

  5. iOS-地图真实坐标表示形式之间转换(double型,int型 互转)

    在开发中可能会遇到这种需求,前端获取的地理坐标并不能在后台以double的形式表示,需要将其转化为其他样式比如:XX度XX分XX秒 的形式表示 进而转化为秒的形式即整形的形式 封装了两个类可直接实现地 ...

  6. mysql 下 计算 两点 经纬度 之间的距离 计算结果排序

    根据经纬度计算距离公式 公式 对上面的公式解释如下: Lung1 Lat1表示A点经纬度, Lung2 Lat2表示B点经纬度: a=Lat1 – Lat2 为两点纬度之差 b=Lung1 -Lung ...

  7. iOS之高德地图定位偏移以及经纬度之间的转换

    高德地图.百度地图以及CLLocationManager等地图的定位功能,从而得到的经纬度坐标会有些偏差,比如系统的CLLocationManager定位得到的是世界标准地理坐标(WGS-84).高德 ...

  8. Mysql: LBS实现查找附近的人 (两经纬度之间的距离)

    1. 利用GeoHash封装成内置数据库函数的简易方案: A:Mysql 内置函数方案,适合于已有业务,新增加LBS功能,增加经纬度字段方可,避免数据迁移 B:Mongodb 内置函数方案,适合中小型 ...

  9. mysql 下 计算 两点 经纬度 之间的距离 含具体sql语句

    mysql取字段逗号分隔的第一个 cover字段为:(admin/LUpiEMD1Pk6U6B,admin/LUpiEMD1Pk6U6B,admin/LUpiEMD1Pk6U6B) 取逗号分隔第一个词 ...

最新文章

  1. LINQ篇:ASP.NET using LINQ(Part One) Scott大师的产物
  2. Tomcat 5.5 配置 MySQL 数据库连接池
  3. Deep Learning 9_深度学习UFLDL教程:linear decoder_exercise(斯坦福大学深度学习教程)...
  4. java 基本的数据类型_Java的基本数据类型介绍
  5. JVM必备指南(转)
  6. 03 ORA系列:ORA-00942 表或视图不存在 table or view does not exist
  7. MySQL 数据库的操作 连接、新增、删除、选择数据库 命令行(带图)
  8. Dijkstra算法实现
  9. String 对象内存分配策略
  10. Unobtrusive JavaScript介绍
  11. DotNetCore 3.0 助力 WPF本地化
  12. ubunt 下 配置samba 服务器
  13. MySQL 优化 —— MySQL 如何使用索引
  14. mysql网络异常_mysql运行过程中因网络或者数据库原因导致的异常
  15. 计算机中那些事儿(四):我眼中的虚拟技术
  16. 如何最大程度地提高cin和cout的效率
  17. 超市管理系统的服务器,超市管理系统
  18. 计算机毕业设计java+jsp学科竞赛管理系统(源码+系统+mysql数据库+Lw文档)
  19. [吴恩达机器学习课程笔记] week four强化学习
  20. python中timeout什么意思_Python爬虫(五)timeout以及retrying的使用

热门文章

  1. bat脚本一键批量修改文件名
  2. 观护帮教之“禁毒防艾”课堂
  3. HTML好看的登录注册界面
  4. 8代cpu安装linux系统吗,8代cpu装win7系统及bios设置教程(支持usb驱动)
  5. 【转】直流无刷电机工作及控制原理
  6. 米家扫地机器人沒有系统重置键_米家扫地机器人恢复出厂设置_米家扫地机器人怎么样恢复出厂设置...
  7. python 生成pdf收据_javascript – 从Django Web应用程序打印收据
  8. 写5个数学建模的经典模型案例和代码
  9. 还不了解NIO ?Java NIO 核心组件详解看一下
  10. 图灵 计算机 ppt,turing machine 图灵机.ppt