请选择 进入手机版 | 继续访问电脑版

12360技术网 - 专业IT技术发表平台

 立即注册  找回密码
查看: 263|回复: 3

各地图坐标转换工具类

[复制链接]

11

主题

17

帖子

169

积分

注册会员

Rank: 2

积分
169
发表于 2020-1-27 04:30:52 | 显示全部楼层 |阅读模式
  1. /** * 坐标转换工具类 * WGS84坐标系:即地球坐标系,国际上通用的坐标系。Earth          (GPS坐标系) * GCJ02坐标系:即火星坐标系,WGS84坐标系经加密后的坐标系。Mars  (谷歌地图(中国)、高德地图、腾讯地图) * BD09坐标系:即百度坐标系,GCJ02坐标系经加密后的坐标系。  Bd09 (百度地图) * 搜狗坐标系、图吧坐标系等,估计也是在GCJ02基础上加密而成的。 (该类地图使用较少) */public class CoordinateConvert {    /**     * 元周率     */    private static final double PI = Math.PI;    /**     * 卫星椭球坐标投影到平面地图坐标系的投影因子     */    private static final double AXIS = 6378245.0;    /**     * 椭球的偏心率 (a^2 - b^2) / a^2     */    private static final double OFFSET = 0.00669342162296594323;    private static final double X_PI = PI * 3000.0 / 180.0;    /**     * 地球半径,单位 m     */    private static final double EARTH_RADIUS = 6378137.0;    /**     * GCJ-02=>BD09 火星坐标系=>百度坐标系     */    public static double[] gcj2BD09(double glat, double glon) {        double x = glon;        double y = glat;        double[] latlon = new double[2];        double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * X_PI);        double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * X_PI);        latlon[0] = z * Math.sin(theta) + 0.006;        latlon[1] = z * Math.cos(theta) + 0.0065;        return latlon;    }    /**     * BD09=>GCJ-02 百度坐标系=>火星坐标系     */    public static double[] bd092GCJ(double glat, double glon) {        double x = glon - 0.0065;        double y = glat - 0.006;        double[] latlon = new double[2];        double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * X_PI);        double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * X_PI);        latlon[0] = z * Math.sin(theta);        latlon[1] = z * Math.cos(theta);        return latlon;    }    /**     * BD09=>WGS84 百度坐标系=>地球坐标系     */    public static double[] bd092WGS(double glat, double glon) {        double[] latlon = bd092GCJ(glat, glon);        return gcj2WGSExactly(latlon[0], latlon[1]);    }    /**     * WGS84=>BD09   地球坐标系=>百度坐标系     */    public static double[] wgs2BD09(double wgLat, double wgLng) {        double[] latlon = wgs2GCJ(wgLat, wgLng);        return gcj2BD09(latlon[0], latlon[1]);    }    /**     * WGS84=>GCJ02   地球坐标系=>火星坐标系     */    public static double[] wgs2GCJ(double wgLat, double wgLng) {        double[] latlon = new double[2];        if (outOfChina(wgLat, wgLng)) {            latlon[0] = wgLat;            latlon[1] = wgLng;            return latlon;        }        double[] deltaD = delta(wgLat, wgLng);        latlon[0] = wgLat + deltaD[0];        latlon[1] = wgLng + deltaD[1];        return latlon;    }    /**     * GCJ02=>WGS84   火星坐标系=>地球坐标系(粗略)     */    public static double[] gcj2WGS(double glat, double glon) {        double[] latlon = new double[2];        if (outOfChina(glat, glon)) {            latlon[0] = glat;            latlon[1] = glon;            return latlon;        }        double[] deltaD = delta(glat, glon);        latlon[0] = glat - deltaD[0];        latlon[1] = glon - deltaD[1];        return latlon;    }    /**     * GCJ02=>WGS84   火星坐标系=>地球坐标系(精确)     */    public static double[] gcj2WGSExactly(double gcjLat, double gcjLng) {        double initDelta = 0.01;        double threshold = 0.000000001;        double dLat = initDelta, dLng = initDelta;        double mLat = gcjLat - dLat, mLng = gcjLng - dLng;        double pLat = gcjLat + dLat, pLng = gcjLng + dLng;        double wgsLat, wgsLng, i = 0;        while (true) {            wgsLat = (mLat + pLat) / 2;            wgsLng = (mLng + pLng) / 2;            double[] tmp = wgs2GCJ(wgsLat, wgsLng);            dLat = tmp[0] - gcjLat;            dLng = tmp[1] - gcjLng;            if ((Math.abs(dLat) < threshold) && (Math.abs(dLng) < threshold)) {                break;            }            if (dLat > 0) {                pLat = wgsLat;            } else {                mLat = wgsLat;            }            if (dLng > 0) {                pLng = wgsLng;            } else {                mLng = wgsLng;            }            if (++i > 10000) {                break;            }        }        double[] latlon = new double[2];        latlon[0] = wgsLat;        latlon[1] = wgsLng;        return latlon;    }    /**     * 根据经纬度,计算两点间的距离     *     * @param longitude1 第一个点的经度     * @param latitude1  第一个点的纬度     * @param longitude2 第二个点的经度     * @param latitude2  第二个点的纬度     * @return 返回距离 单位米     */    public static double getDistance(double longitude1, double latitude1, double longitude2, double latitude2) {        // 纬度        double lat1 = Math.toRadians(latitude1);        double lat2 = Math.toRadians(latitude2);        // 经度        double lng1 = Math.toRadians(longitude1);        double lng2 = Math.toRadians(longitude2);        // 纬度之差        double a = lat1 - lat2;        // 经度之差        double b = lng1 - lng2;        // 计算两点距离的公式        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +                Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(b / 2), 2)));        // 弧长乘地球半径, 返回单位: 米        s =  s * EARTH_RADIUS;        return s;    }    private static double[] delta(double wgLat, double wgLng) {        double[] latlng = new double[2];        double dLat = transformLat(wgLng - 105.0, wgLat - 35.0);        double dLng = transformLng(wgLng - 105.0, wgLat - 35.0);        double radLat = wgLat / 180.0 * PI;        double magic = Math.sin(radLat);        magic = 1 - OFFSET * magic * magic;        double sqrtMagic = Math.sqrt(magic);        dLat = (dLat * 180.0) / ((AXIS * (1 - OFFSET)) / (magic * sqrtMagic) * PI);        dLng = (dLng * 180.0) / (AXIS / sqrtMagic * Math.cos(radLat) * PI);        latlng[0] = dLat;        latlng[1] = dLng;        return latlng;    }    private static boolean outOfChina(double lat, double lon) {        if (lon < 72.004 || lon > 137.8347) {            return true;        }        if (lat < 0.8293 || lat > 55.8271) {            return true;        }        return false;    }    private static double transformLat(double x, double y) {        double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));        ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0;        ret += (20.0 * Math.sin(y * PI) + 40.0 * Math.sin(y / 3.0 * PI)) * 2.0 / 3.0;        ret += (160.0 * Math.sin(y / 12.0 * PI) + 320 * Math.sin(y * PI / 30.0)) * 2.0 / 3.0;        return ret;    }    private static double transformLng(double x, double y) {        double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));        ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0;        ret += (20.0 * Math.sin(x * PI) + 40.0 * Math.sin(x / 3.0 * PI)) * 2.0 / 3.0;        ret += (150.0 * Math.sin(x / 12.0 * PI) + 300.0 * Math.sin(x / 30.0 * PI)) * 2.0 / 3.0;        return ret;    }    /**     * 精确计算两个除数的结果     * @param d1    除数     * @param d2    被除数     * @param digit 精度     * @return: double     */    public static double calDvi(double d1, double d2, int digit) {        if (d2 == 0) {            return 0;        }        BigDecimal bi1 = BigDecimal.valueOf(d1);        BigDecimal bi2 = BigDecimal.valueOf(d2);        return bi1.divide(bi2, digit, RoundingMode.HALF_UP).doubleValue();    }}
复制代码
                                                                                                                                       
                                                    
  • 点赞                        2                        
  • 收藏                        
  • 分享                                                                                                                        
  •                                                         
                                      
    • 文章举报                           
                                                
                                                                        
                                            
                                                        AWen_Jack                                                                发布了11 篇原创文章 · 获赞 3 · 访问量 2152                                                                                            私信                                                            关注
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x




上一篇:可行性研究、需求分析
下一篇:声音场景分类问题探讨
回复

使用道具 举报

0

主题

9

帖子

199

积分

注册会员

Rank: 2

积分
199
发表于 2020-1-28 17:51:16 | 显示全部楼层
既然你诚信诚意的推荐了,那我就勉为其难的看看吧![www.12360.co]
回复

使用道具 举报

0

主题

25

帖子

535

积分

高级会员

Rank: 4

积分
535
发表于 2020-2-10 00:17:34 | 显示全部楼层
这个帖子不回对不起自己![www.12360.co]
回复

使用道具 举报

0

主题

7

帖子

157

积分

注册会员

Rank: 2

积分
157
发表于 2020-2-11 00:42:01 | 显示全部楼层
这东西我收了!谢谢楼主![www.12360.co]
回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

12360技术网

GMT+8, 2020-2-22 12:42 , Processed in 0.086057 second(s), 26 queries .

本网站内容收集于互联网,Www.12360.Co不承担任何由于内容的合法性及健康性所引起的争议和法律责任。 欢迎大家对网站内容侵犯版权等不合法和不健康行为进行监督和举报。

© 2019-2020 Www.12360.Co

快速回复 返回顶部 返回列表