gps经纬度转百度地图经纬度

78、gps经纬度转百度地图经纬度

需求:把得到的gps的基站数据的经纬度转换成百度的经纬度,适配百度地图

package com.lzh.springcloud;

import cn.hutool.core.codec.Base64;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**
 * gps经纬度转百度地图经纬度
 *
 * @author LZH
 * @version 1.0
 * @date 2023/04/14 19:32:51
 */
public class Map {
    public static void main(String[] args) {
        String url = "http://api.map.baidu.com/ag/coord/convert?from=0&to=4&x=109.840836&y=25.848595";
        String back = HttpUtil.get(url);
        String x = Base64.decodeStr(JSONUtil.parseObj(back).getStr("x"));
        String y = Base64.decodeStr(JSONUtil.parseObj(back).getStr("y"));
        System.out.println("精度:"+x);
        System.out.println("纬度:"+y);

        double[] doubles = CoordinateTransformUtil.wgs84tobd09(109.840836, 25.848595);
        System.out.println("精度:"+doubles[0]);
        System.out.println("纬度:"+doubles[1]);

        String apiUrl = "https://api.map.baidu.com/geoconv/v1/?coords=109.840836,25.848595&from=1&to=5&ak=百度服务的ak";
        String apiBack = HttpUtil.get(apiUrl);
        System.out.println(apiBack);	
        JSONObject jsonObject = JSONObject.parseObject(apiBack);
        if (jsonObject.getInteger("status") == 0){
            JSONArray result = jsonObject.getJSONArray("result");
            result.stream().forEach(r->{
                JSONObject jsonObject1 = JSONObject.parseObject(r.toString());
                System.out.println("精度:"+jsonObject1.get("x"));
                System.out.println("纬度:"+jsonObject1.get("y"));
            });

        }

    }
}

工具类:

package com.lzh.springcloud;

import java.math.BigDecimal;

/**
 * gps转百度经纬度
 *
 * @author LZH
 * @version 1.0
 * @date 2023/04/14 19:33:16
 */
public class CoordinateTransformUtil {
    static int B_DIV_SCALE = 15;
    static BigDecimal x_pi = new BigDecimal("3.14159265358979324").multiply(new BigDecimal("3000")).divide(new BigDecimal("180"), B_DIV_SCALE, BigDecimal.ROUND_HALF_UP);
    // π
    static BigDecimal pi = new BigDecimal("3.1415926535897932384626");
    // 长半轴
    static BigDecimal a = new BigDecimal("6378245");
    // 扁率
    static BigDecimal ee = new BigDecimal("0.00669342162296594323");
    static BigDecimal b_1 = new BigDecimal("-1");
    static BigDecimal b_2 = new BigDecimal("10");
    static BigDecimal b_3 = new BigDecimal("2");
    static BigDecimal b_4 = new BigDecimal("105");
    static BigDecimal b_5 = new BigDecimal("3");
    static BigDecimal b_6 = new BigDecimal("35");
    static BigDecimal b_7 = new BigDecimal("160");
    static BigDecimal b_8 = new BigDecimal("1");
    static BigDecimal b_9 = new BigDecimal("150");
    static BigDecimal b_10 = new BigDecimal("180");

    static BigDecimal b_11 = new BigDecimal("0.00002");
    static BigDecimal b_12 = new BigDecimal("0.000003");
    static BigDecimal b_13 = new BigDecimal("0.0065");
    static BigDecimal b_14 = new BigDecimal("0.006");

    /**
     * WGS坐标转百度坐标系(BD-09)
     *
     * @param lng WGS84坐标系的经度
     * @param lat WGS84坐标系的纬度
     * @return 百度坐标数组
     */
    public static double[] wgs84tobd09(double lng, double lat) {
        double[] gcj = wgs84togcj02(lng, lat);
        double[] bd09 = gcj02tobd09(gcj[0], gcj[1]);
        return bd09;
    }

    /**
     * 火星坐标系(GCJ-02)转百度坐标系(BD-09)
     *
     * @param lng 火星坐标经度
     * @param lat 火星坐标纬度
     * @return 百度坐标数组
     * @see 谷歌、高德——>百度
     */
    public static double[] gcj02tobd09(double lng, double lat) {
        BigDecimal b_lng = new BigDecimal(lng);
        BigDecimal b_lat = new BigDecimal(lat);
        BigDecimal z = new BigDecimal(Math.sqrt(b_lng.multiply(b_lng).add(b_lat.multiply(b_lat)).doubleValue())).add(b_11.multiply(new BigDecimal(Math.sin(b_lat.multiply(x_pi).doubleValue()))));
        BigDecimal theta = new BigDecimal(Math.atan2(b_lat.doubleValue(), b_lng.doubleValue())).add(b_12.multiply(new BigDecimal(Math.cos(b_lng.multiply(x_pi).doubleValue()))));
        BigDecimal bd_lng = z.multiply(new BigDecimal(Math.cos(theta.doubleValue()))).add(b_13);
//        z * Math.cos(theta) + 0.0065;
        BigDecimal bd_lat = z.multiply(new BigDecimal(Math.sin(theta.doubleValue()))).add(b_14);
        return new double[]{bd_lng.doubleValue(), bd_lat.doubleValue()};
    }

    /**
     * WGS84转GCJ02(火星坐标系)
     *
     * @param lng WGS84坐标系的经度
     * @param lat WGS84坐标系的纬度
     * @return 火星坐标数组
     */
    public static double[] wgs84togcj02(double lng, double lat) {
        BigDecimal b_lng = new BigDecimal(lng + "");
        BigDecimal b_lat = new BigDecimal(lat + "");
        if (out_of_china(b_lng, b_lat)) {
            return new double[]{b_lng.doubleValue(), b_lat.doubleValue()};
        }
        BigDecimal dlat = transformlat(b_lng.subtract(b_4), b_lat.subtract(b_6));
        BigDecimal dlng = transformlng(b_lng.subtract(b_4), b_lat.subtract(b_6));
        BigDecimal radlat = b_lat.divide(b_10, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(pi);
        BigDecimal magic = new BigDecimal(Math.sin(radlat.doubleValue()));
        magic = b_8.subtract(ee.multiply(magic).multiply(magic));
        BigDecimal sqrtmagic = new BigDecimal(Math.sqrt(magic.doubleValue()));
        dlat = (dlat.multiply(b_10)).divide((a.multiply(b_8.subtract(ee))).divide((magic.multiply(sqrtmagic)), B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(pi), B_DIV_SCALE, BigDecimal.ROUND_HALF_UP);
        dlng = (dlng.multiply(b_10)).divide((a.divide(sqrtmagic, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(Math.cos(radlat.doubleValue())).multiply(pi))), B_DIV_SCALE, BigDecimal.ROUND_HALF_UP);
        BigDecimal mglat = b_lat.add(dlat);
        BigDecimal mglng = b_lng.add(dlng);
        return new double[]{mglng.doubleValue(), mglat.doubleValue()};
    }

    /**
     * 纬度转换
     *
     * @param lng
     * @param lat
     * @return
     */
    public static BigDecimal transformlat(BigDecimal lng, BigDecimal lat) {
        BigDecimal bet = b_1.multiply(b_2).multiply(b_2)
                .add(b_3.multiply(lng))
                .add(b_5.multiply(lat))
                .add(b_3.divide(b_2, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(lat).multiply(lat))
                .add(b_8.divide(b_2, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(lng).multiply(lat))
                .add(b_3.divide(b_2, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(Math.sqrt(Math.abs(lng.doubleValue())))));
        bet = bet.add((b_3.multiply(b_2).multiply(new BigDecimal(Math.sin(b_3.multiply(b_5).multiply(lng).multiply(pi).doubleValue())))
                .add(b_3.multiply(b_2).multiply(new BigDecimal(Math.sin(b_3.multiply(lng).multiply(pi).doubleValue()))))).multiply(b_3).divide(b_5, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP));
        bet = bet.add((b_3.multiply(b_2).multiply(new BigDecimal(Math.sin(lat.multiply(pi).doubleValue())))
                .add(b_3.multiply(b_3).multiply(b_2).multiply(new BigDecimal(Math.sin(lat.divide(b_5, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(pi).doubleValue()))))).multiply(b_3).divide(b_5, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP));
        bet = bet.add((b_7.multiply(new BigDecimal(Math.sin(lat.divide(b_5.multiply(b_3).multiply(b_3), B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(pi).doubleValue())))
                .add(b_7.multiply(b_3).multiply(new BigDecimal(Math.sin(lat.multiply(pi).divide(b_5.multiply(b_2), B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).doubleValue()))))).multiply(b_3).divide(b_5, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP));
        return bet;
    }

    /**
     * 经度转换
     *
     * @param lng
     * @param lat
     * @return
     */
    public static BigDecimal transformlng(BigDecimal lng, BigDecimal lat) {
        BigDecimal bet = b_2.multiply(b_2).multiply(b_5).add(lng).add(b_3.multiply(lat)).add(b_8.divide(b_2, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(lng).multiply(lng))
                .add(b_8.divide(b_2, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(lng).multiply(lat)).add(b_8.divide(b_2, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(Math.sqrt(Math.abs(lng.doubleValue())))));
        bet = bet.add((b_3.multiply(b_2).multiply(new BigDecimal(Math.sin(b_3.multiply(b_5).multiply(lng).multiply(pi).doubleValue())))
                .add(b_3.multiply(b_2).multiply(new BigDecimal(Math.sin(b_3.multiply(lng).multiply(pi).doubleValue()))))).multiply(b_3).divide(b_5, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP));
        bet = bet.add((b_3.multiply(b_2).multiply(new BigDecimal(Math.sin(lng.multiply(pi).doubleValue())))
                .add(b_3.multiply(b_3).multiply(b_2).multiply(new BigDecimal(Math.sin(lng.divide(b_5, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(pi).doubleValue()))))).multiply(b_3).divide(b_5, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP));
        bet = bet.add((b_9.multiply(new BigDecimal(Math.sin(lng.divide(b_3.multiply(b_3).multiply(b_5), B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(pi).doubleValue())))
                .add(b_9.multiply(b_3).multiply(new BigDecimal(Math.sin(lng.divide(b_5.multiply(b_2), B_DIV_SCALE, BigDecimal.ROUND_HALF_UP).multiply(pi).doubleValue())))).multiply(b_3).divide(b_5, B_DIV_SCALE, BigDecimal.ROUND_HALF_UP)));
        return bet;
    }

    /**
     * 判断是否在国内,不在国内不做偏移
     *
     * @param lng
     * @param lat
     * @return
     */
    public static boolean out_of_china(BigDecimal lng, BigDecimal lat) {
        if (lng.compareTo(new BigDecimal("73.66")) < 0 || lng.compareTo(new BigDecimal("135.05")) > 0) {
            return true;
        } else if (lat.compareTo(new BigDecimal("3.86")) < 0 || lat.compareTo(new BigDecimal("53.55")) > 0) {
            return true;
        }
        return false;
    }
}

一共三种方式:

1、第一种调用接口(网上搜到的),精确度还可以(调用次数好像是每天10万次)

2、工具类得到的,精确度最差

3、百度官网的api,标准(个人认证每天只能调用5000次)

结果如下所示:

在这里插入图片描述

申请百度地图开发者认证,很快就认证成功了

创建应用

在这里插入图片描述

如果接口报错210,app ip认证问题,修改ip白名单限制

在这里插入图片描述

设置为0.0.0.0/0,不限制,然后再次访问就可以成功了

具体业务实现:

批量更新数据,一次更新5000条

使用 update 表名 set aa = case when id =1 then bb case when id =2 then cc end where id in(1,2)

public void updateCellId(){
        int index = 1;
        int from = 0;
        Integer size = 5000;
        List<Cellidnew> info = this.getBaseMapper().getInfo(from, size);
        String sqlAll = "update 表名 set LNG_BD_UTILS = %s ,LAT_BD_UTILS = %s where id in (%s)";

        String salSub = " when id = %s then %s ";
        String salSubStart = " case ";
        String salSubEnd = " end ";

//        当数据不为空的时候
        while (ObjectUtil.isNotEmpty(info)){
            System.out.println("这是第 "+index+" 次");
            StringBuilder lngsb = new StringBuilder();
            StringBuilder latsb = new StringBuilder();
            lngsb.append(salSubStart);
            latsb.append(salSubStart);
            List<Cellidnew> list = new ArrayList<>();
            info.forEach(i->{
                if (ObjectUtil.isNotEmpty(i.getLng()) && ObjectUtil.isNotEmpty(i.getLat())){
                    double[] doubles = CoordinateTransformUtil.wgs84tobd09(i.getLng(), i.getLat());
                    lngsb.append(String.format(salSub,i.getId(),doubles[0]));
                    latsb.append(String.format(salSub,i.getId(),doubles[1]));
                }
            });
            lngsb.append(salSubEnd);
            latsb.append(salSubEnd);
//            获取id
            String collect = info.stream().map(i -> {
                return i.getId().toString();
            }).collect(Collectors.joining(","));

//            批量更新数据
            String executeSql = String.format(sqlAll, lngsb.toString(), latsb.toString(), collect);
            if (ObjectUtil.isNotEmpty(executeSql)){
//                执行脚本插入语句
                this.getBaseMapper().executeSql(executeSql);
            }
            index++;
            from = (index - 1) * size;
            //再次查询数据进行循环
            info = this.getBaseMapper().getInfo(from, size);
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值