GIS, 经纬度与度分秒互相转换算法


一、前言

我们常见的经纬度通常有两种表达格式,一种是小数点的方式,如 113.22145 度,另外一种是度分秒的形式,如 113°13′17.22″ 、113度13分17.22秒。这两种格式我们在数据处理的时候都会用到,本文简要介绍下经纬度与度分秒互相转换的方式。

二、转换算法

经纬度 转 度分秒

假设有个纬度是23.12345,整数的部分23 这个就是转换后的度数(°); 小数的部分0.12345 * 60 = 7.407 ,取整数的部分,7(‘)就是转换后的分数;分数计算后的小数部分,也就是0.407 * 60 = 24.42,24.42(")就是转换后的秒数。因此23.12345转换后就是23° 7’ 24.42"。

度分秒 转 经纬度

假设有个度数是23° 7’ 24.42",转换公式 : x度 y分 z秒 = x + y/60 + z/3600 度

(23) + (7/60) + (24.42/3600) = 23 + 0.11666 + 0.00678333 = 23.123443

2.1 javascript实现

// 经纬度转度分秒
function transformDMS(degree, direction) {
            var D = plusZeroAtHead(Math.floor(degree));
        var M = plusZeroAtHead(Math.floor((degree - D) * 60));
        var S = plusZeroAtHead(Math.floor(((degree - D) * 60 - M) * 60));
        var result = D + "°" + M + "′" + S + "″";

        // 如果是个位数, 则在首位加 0
        function plusZeroAtHead(num) {
                if (num > -10 && num < 0) {
                        num = "-0" + Math.abs(num)
                }
                if (num > 0 && num < 10) {
                        return "0" + num
                }
                return num;
        }
        if (direction === "lon") {
                D > 0 ? result += "E" : result += "W";
                return result;
        }
        if (direction === "lat") {
                D > 0 ? result += "N" : result += "S";
                return result;
        }
        return result;
}
// 度分秒 转 经纬度 
function dsturnDeg(value){ 
    var du = value.split("°")[0];//度 
    var fen = value.split("°")[1].split("'")[0];//分 
    var miao = value.split("°")[1].split("'")[1].split('"')[0];//秒 
    return Math.abs(du) + "." + (Math.abs(fen)/60 + Math.abs(miao)/3600); 
}

2.2 C#实现

// 经纬度转度分秒
private string LatLngToGPS(string text) 
{     
    string result = "";      
    string[] ary = text.Trim().Split('.'); 

    if (ary.Length == 2)     
    {         
        double degree, minute, second, temp;          
        //ex. 21.12345         
        if (double.TryParse(ary[0], out degree) && double.TryParse(ary[1], out temp))         
        {             
            //取小數位 0.12345             
            temp = temp / System.Math.Pow(10, ary[1].Length);              
            //分只留下整數位             
            minute = Math.Floor(temp * 60);              
            //取分剩下的小數位             
            double temp1 = (temp * 60) - Math.Floor(temp * 60);              
            second = temp1 * 60;              
            result = degree.ToString() + "°" + minute.ToString("00") + "\'" + second.ToString() + "\"";         
        }     
    }      
    return result; 
}

// 度分秒 转 经纬度
private string GPSToLatLng(string text) 
{     
    string result = "";      
    text = text.Trim();      
    //必須有度分秒才可進行轉換     
    if (text.IndexOf('°') != -1 && text.IndexOf('\'') != -1 && text.IndexOf('\"') != -1)     
    {         
        double degree, minute, second;          
        //取得度分秒         
        if (double.TryParse(text.Split('°')[0], out degree) &&  
            double.TryParse(text.Split('°')[1].Split('\'')[0], out minute) &&
            double.TryParse(text.Split('°')[1].Split('\'')[1].Split('\"')[0], out second)
        )         
        {             
            //x度 y分 z秒 = x + y/60 + z/3600 度              
            result = (degree + (minute / 60) + (second / 3600)).ToString();         
        }     
    }             
    return result; 
}

2.3 java 实现

package com.demo;

import lombok.extern.slf4j.Slf4j;


/*************************************
 *Class Name: LatLngUtil
 *Description: <度分秒,度分,与经纬度互转工具类>
 *@author: Seminar
 *@create: 2021/5/24
 *@since 1.0.0
 *************************************/
@Slf4j
public class LatLngUtil {

    /**
     * 将经纬度转换为度分秒格式
     *
     * @param du 116.41884740.0897315
     * @return 116°25'7.85"       40°5'23.03"
     */
    public static String latLng2Dfm(double du) {
        int du1 = (int) du;
        double tp = (du - du1) * 60;
        int fen = (int) tp;
        String miao = String.format("%.2f", Math.abs(((tp - fen) * 60)));
        return du1 + "°" + Math.abs(fen) + "'" + miao + "\"";
    }

    /**
     * 度分秒转经纬度
     *
     * @param dms 116°25'7.85"
     * @return 116.418847
     */
    public static double dfm2LatLng(String dms) {
        if (dms == null) return 0;
        try {
            dms = dms.replace(" ", "");
            String[] str2 = dms.split("°");
            if (str2.length < 2) return 0;
            int d = Integer.parseInt(str2[0]);
            String[] str3 = str2[1].split("\'");
            if (str3.length < 2) return 0;
            int f = Integer.parseInt(str3[0]);
            String str4 = str3[1].substring(0, str3[1].length() - 1);
            double m = Double.parseDouble(str4);

            double fen = f + (m / 60);
            double du = (fen / 60) + Math.abs(d);
            if (d < 0) du = -du;
            return Double.parseDouble(String.format("%.7f", du));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 将经纬度转换为度分格式
     *
     * @param du 116.418847      40.0897315
     * @return 116°25'  40°5'
     */
    private static String latLng2Df(double du) {
        int du1 = (int) du;
        double tp = (du - du1) * 60;
        int fen = (int) tp;
        return du1 + "°" + Math.abs(fen) + "'";
    }

    /**
     * 度分转经纬度
     * 全球经纬度的取值范围为:纬度-90~90,经度-180~180
     * 度分转换: 将度分单位数据转换为度单位数据,公式:度=度+分/60
     * 例如: 经度 = 116°20.12',纬度 = 39°12.34'
     * 经度 = 116 + 20.12 / 60 = 116.33533°
     * 纬度 = 39 + 12.34 / 60 = 39.20567°
     *
     * @param dm 4005.38389 ddmm.mmmmm
     * @return 40.0897315
     * 11616.02846 dddmm.mmmmm
     * 116.267141
     */
    public static double df2LatLng(String dm) {
        if (dm == null) {
            return 0;
        }
        try {
            dm = dm.replace(" ", "");
            int d = parseInteger(dm.substring(0, dm.lastIndexOf(".") - 2));
            // 兼容经纬度的转换
            double fen = Double.parseDouble(dm.substring(String.valueOf(d).length()));

            double lat = (fen / 60) + Math.abs(d);
            if (lat < 0) {
                lat = -lat;
            }
            return Double.parseDouble(String.format("%.7f", lat));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * dms转经纬度
     * 41951158     14371952
     * 116.5309944  39.9220889
     *
     * @param dms dms 经纬度
     * @return
     */
    public static double dfm2Du(Double dms) {
        int degree = (int) (dms / 360000);
        int minute = (int) ((dms - degree * 360000) / 6000);
        double second = (double) ((dms - degree * 360000 - minute * 6000) / 100.00);
        double digitalDegree = 0.0;
        double num = 60;
        digitalDegree += degree;
        digitalDegree += minute / num;
        digitalDegree += (second / (num * num));

        return Double.parseDouble(String.format("%.7f", digitalDegree));
    }

    public static Integer parseInteger(String str) {
        if (str == null || str.isEmpty()) {
            return 0;
        }
        return Integer.valueOf(str);
    }

    public static void main(String[] args) {
        double dfLng = 11616.02846; // 经度  dddmm.mmmmm
        double dfLat = 4005.38389; // 纬度 ddmm.mmmm
        double lng = 116.1602846;
        double lat = 40.0897315;

        log.info("   度分转经纬度:{} {}", df2LatLng(String.valueOf(dfLng)), df2LatLng(String.valueOf(dfLat)));
        log.info("   经纬度转度分:{} {}", latLng2Df(lng), latLng2Df(lat));

        String dfmLng = "116°25'7.85"; // 经度  ddd°mm'm.mm"
        String dfmLat = "40°5'23.03"; // 纬度 dd°mm'm.mm"
        log.info(" 度分秒转经纬度:{} {}", dfm2LatLng(dfmLng), dfm2LatLng(dfmLat));
        log.info(" 经纬度转度分秒:{} {}", latLng2Dfm(lng), latLng2Dfm(lat));


        Double dfmLng2 = 41951158d; // 经度
        Double dfmLat2 = 14371952d; // 纬度
        log.info("度分秒转经纬度2:{} {}", dfm2Du(dfmLng2), dfm2Du(dfmLat2));
    }

}

三、转换的意义和应用

3.1 意义

  • 地理定位:经纬度是地球表面上每个点的独特标识,通过经纬度转换,我们可以准确地确定一个地理位置。
  • 导航与定位:经纬度是现代导航系统的基础,比如GPS定位就是通过经纬度转换来确定位置。
  • 地图与测绘:经纬度转换在地图制作和测绘领域具有重要意义,能够帮助绘制准确的地图。

3.2 应用

  • 航海与航空领域:经纬度转换在导航系统中起着核心作用,帮助船只和飞机准确确定位置。
  • 地图与导航应用:经纬度转换可以用于绘制地图、路径规划等,为我们提供准确的导航信息。
  • 气象与地震研究:通过经纬度转换,可以根据不同地区的经纬度信息进行气象预测和地震研究。
  • 旅游与出游指南:经纬度转换可以用于旅游指南、地点推荐等,帮助游客找到感兴趣的景点。

四、总结

综上所述,经纬度转换是一个简单而实用的工具,对于地理位置的描述和确定具有重要意义。了解经纬度转换的意义、常用方法和应用领域,可以帮助我们更好地利用地理信息,并为各行各业带来更多便利。无论是航海领域中的航行定位,还是日常出行中的导航服务,经纬度转换都是不可或缺的。因此,进一步了解并使用经纬度转换,将有助于我们更好地掌握地理信息,并在各自的领域中获得更多的发展机遇。


参考:
「GIS算法」GIS中的经纬度与度分秒互相转换算法
经纬度转换

  • 19
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

gis分享者

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

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

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

打赏作者

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

抵扣说明:

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

余额充值