经纬度转换

经纬度转换

北纬为正数,南纬为负数。东经正数,西经为负数
北纬和南纬,分别用"N"和"S"表示
东经和西经,分别用"E"和"W"表示
经度的每一度被分为60分,每一分被分为60秒。

度分秒转小数公式:
N 39°34’14.95"
= 39 = 39
= 34 / 60 = 0.5666666666666667
= 14.95 / 3600 = 0.0041527777777778‬
= 将计算结果相加后:39 + 0.5666666666666667 + 0.0041527777777778‬ 最终等于=>:39.57081944444444‬

小数转度分秒公式
39.57081944444444‬
= 39 = 39°
= 0.57081944444444‬ * 60 = 34.2491666666664 取整后 = 34’
= 0.2491666666664 * 60 =14.949999999984‬ 四舍五入后 = 14.95"
= 将计算结果合并后,最终等于=>:39°34’14.95"

package util;

import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.regex.Pattern;

/**
 * 经纬度工具类
 */
public class JWDUtil {

    /**
     * 经纬度格式转换
     * Description: N 39°34'14.95"   ==>  39.570819445
     *
     * @param jwd
     * @return
     */
    public static String dmsToDouble(String jwd) {
        if (StringUtils.isEmpty(jwd)) return null;
        String firstStr = jwd.substring(0, 1);
        String regEx = "[EWNS°'\"]";
        Pattern compile = Pattern.compile(regEx);
        String[] split = compile.split(jwd);
        if (4 != split.length) return null;

        BigDecimal b = new BigDecimal(split[1].trim())
                .add( new BigDecimal(split[2].trim()).divide(BigDecimal.valueOf(60.0), 9, BigDecimal.ROUND_HALF_UP) )
                .add( new BigDecimal(split[3].trim()).divide(BigDecimal.valueOf(3600.0), 9, BigDecimal.ROUND_HALF_UP) );
        if ("W".equals(firstStr) || "S".equals(firstStr)) {
            b = b.negate();
        }
        return b.toPlainString();
    }

    /**
     * 经纬度格式转换
     * Description: "39.570819445"   ==>  N 39°34'14.95"
     *               "39"             ==>  N 39°00'00.00"
     *               "39.0"           ==>  N 39°00'00.00"
     *               "-39"            ==>  S 39°00'00.00"
     *               "-39.0"          ==>  S 39°00'00.00"
     *              " +39.570819445"  ==>  N 39°34'14.95"
     *              " -39.570819445"  ==>  S 39°34'14.95"
     *
     * @param jwd
     * @param isJd  true:经度;false:纬度
     * @return
     */
    public static String doubleToDms(String jwd, boolean isJd) {
        if (StringUtils.isEmpty(jwd) || !isNumeric(jwd)) return null;
        String firstStr = jwd.substring(0, 1);
        StringBuilder sb = new StringBuilder();
        if (isJd) {
            // 东西经度
            sb.append("-".equals(firstStr) ? "W " : "E ");
        } else {
            // 南北纬度
            sb.append("-".equals(firstStr) ? "S " : "N ");
        }

        BigDecimal big = new BigDecimal(jwd);
        Integer deg = big.intValue();
        BigDecimal rem = big.subtract(new BigDecimal(deg));
        Integer min = rem.multiply(BigDecimal.valueOf(60)).intValue();
        BigDecimal sec = (rem.multiply( BigDecimal.valueOf(60) ).subtract(BigDecimal.valueOf(min)))
                .multiply(BigDecimal.valueOf(60)).setScale(2, BigDecimal.ROUND_HALF_UP);

        if ("-".equals(firstStr)) {
            // 度 分 秒
            deg = Math.abs(deg);
            min = Math.abs(min);
            sec = sec.negate();
        }
        DecimalFormat g2 = new DecimalFormat("00");
        DecimalFormat g3 = new DecimalFormat("00.00");
        sb.append(deg).append("°");
        return sb.append(g2.format(min)).append("'").append(g3.format(sec)).append("\"").toString();
    }

    /**
     * 判断字符串是否是数字
     * 校验值为true :"+12"、"12"、"-12"、"-12.5"、"+12.5"、"127777"
     * 校验值为fasle:"+12.5a"、"q2.5"、"12.-5"、"12..5"、""、" "、null
     * @param str
     * @return
     */
    public static boolean isNumeric(String str) {
        if (StringUtils.isEmpty(str)) return false;
        Pattern pattern = Pattern.compile("(-|\\+)?[0-9]+.?[0-9]*");
        return pattern.matcher(str).matches();
    }

    public static void main(String[] args) {
        String s = dmsToDouble("N 39°34'14.95\"");
        System.out.println(s);
        String s1 = doubleToDms(s, false);
        System.out.println(s1);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值