经纬度转换工具类,秒无法准确显示解决方案

场景:经纬度转换,dms转十进制,十进制转度分秒



import lombok.extern.slf4j.Slf4j;

import java.text.DecimalFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author: pangyq
 * @CreateTime: 2024-10-16  08:38
 * @Description: TODO
 * @Version: 1.0
 */
@Slf4j
public class LongitudeAndLatitudeUtils {
    private StringBuilder isValidLatitude(String latitude) {
        StringBuilder sb = new StringBuilder();
        try {
            String regex = "^([1-8]?\\d(?:\\.\\d+)?|90)(?:°(\\d{1,2})'([0-5]?\\d)\"([NS]))?$";
            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(latitude);
            if (!matcher.matches()) {
                return sb.append("the latitude data format error;");
            }
            if (null != matcher.group(2)) {
                int degrees = Integer.parseInt(matcher.group(1));
                int minutes = Integer.parseInt(matcher.group(2));
                int seconds = Integer.parseInt(matcher.group(3));
                String direction = matcher.group(4);
                double decimalDegrees = degrees + minutes / 60.0 + seconds / 3600.0;
                if (direction.contains("S")) {
                    decimalDegrees = -decimalDegrees;
                }
                return decimalDegrees >= -90.0 && decimalDegrees <= 90.0 ? sb.append("") : sb.append("the latitude data value range error; ");
            } else {
                double decimalDegrees = Double.parseDouble(latitude);
                return decimalDegrees >= -90.0 && decimalDegrees <= 90.0 ? sb.append("") : sb.append("the latitude data value range error; ");
            }
        } catch (NumberFormatException e) {
            log.error("Error parsing latitude", e);
            return sb.append("the latitude data format error; ");
        }
    }

    private StringBuilder isValidLongitude(String longitude) {
        StringBuilder sb = new StringBuilder();
        String regex = "^([1-8]?\\d(?:\\.\\d+)?|180)(?:°(\\d{1,2})'([0-5]?\\d)\"([EW]))?$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(longitude);
        if (!matcher.matches()) {
            return sb.append("the longitude data format error; ");
        }
        if (null != matcher.group(2)) {
            int degrees = Integer.parseInt(matcher.group(1));
            int minutes = Integer.parseInt(matcher.group(2));
            int seconds = Integer.parseInt(matcher.group(3));
            String direction = matcher.group(4);
            double decimalDegrees = degrees + minutes / 60.0 + seconds / 3600.0;
            if (direction.contains("W")) {
                decimalDegrees = -decimalDegrees;
            }
            return decimalDegrees >= -180.0 && decimalDegrees <= 180.0 ? sb.append("") : sb.append("the longitude data value range error; ");
        } else {
            double decimalDegrees = Double.parseDouble(longitude);
            return decimalDegrees >= -180.0 && decimalDegrees <= 180.0 ? sb.append("") : sb.append("the longitude data value range error; ");
        }
    }

    public static double convertLatitudeAndLongitude(String inputCoordinate) {

        final String DECIMAL_FORMAT = "0.0000000";
        if (inputCoordinate == null || !inputCoordinate.matches("\\d+°\\d+'\\d+\"[NSWE]")) {
            throw new IllegalArgumentException("Invalid DMS format: " + inputCoordinate);
        }
        try {
            String[] parts = inputCoordinate.split("[°'\"]");
            int du = Integer.parseInt(parts[0]);
            double min = Double.parseDouble(parts[1]);
            double sec = Double.parseDouble(parts[2]);
            double decimalDegree = du + (min / 60) + (sec / 3600);

            char direction = inputCoordinate.charAt(inputCoordinate.length() - 2);
            if (direction == 'W' || direction == 'S') {
                decimalDegree *= -1;
            }

            DecimalFormat df = new DecimalFormat(DECIMAL_FORMAT);
            return Double.parseDouble(df.format(decimalDegree));
        } catch (NumberFormatException | ArrayIndexOutOfBoundsException e) {
            throw new IllegalArgumentException("Error parsing DMS string: " + inputCoordinate, e);
        }
    }

    public static String convertToDMS(double decimalDegree, boolean isLatitude) {
        if (Double.isNaN(decimalDegree) || Double.isInfinite(decimalDegree)) {
            throw new IllegalArgumentException("Invalid input: decimalDegree must be a finite number.");
        }

        try {
            boolean isNegative = decimalDegree < 0;
            decimalDegree = Math.abs(decimalDegree);

            int degrees = (int) decimalDegree;
            double minutes = (decimalDegree - degrees) * 60;
            int mins = (int) minutes;
            double seconds = (minutes - mins) * 60;

//            DecimalFormat df = new DecimalFormat("0.0");
            DecimalFormat df = new DecimalFormat("0");
            String formattedMins = df.format(mins);
            String formattedSecs = df.format(seconds);
            String direction;
            if (isLatitude) {
                direction = isNegative ? "S" : "N";
            } else {
                direction = isNegative ? "W" : "E";
            }

            return degrees + "°" + formattedMins + "'" + formattedSecs + "\"" + direction;
        } catch (Exception e) {
            throw new RuntimeException("An error occurred while converting to DMS format: " + e.getMessage(), e);
        }
    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

庞胖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值