Java實(shí)現(xiàn)度分秒坐標(biāo)轉(zhuǎn)十進(jìn)制度
前言
在地理信息系統(tǒng)(GIS)、導(dǎo)航、測(cè)繪等領(lǐng)域,精確地表示和轉(zhuǎn)換地理位置坐標(biāo)是一項(xiàng)基本而重要的任務(wù)。地理坐標(biāo)通常以經(jīng)度和緯度的形式表示,它們可以采用度分秒(DMS)或十進(jìn)制度(DD)兩種格式。度分秒是一種傳統(tǒng)的表示方式,它將角度分為度、分和秒,而十進(jìn)制度則以小數(shù)形式直接表示角度,更便于計(jì)算機(jī)處理。隨著技術(shù)的發(fā)展,十進(jìn)制度因其精確性和便捷性在現(xiàn)代應(yīng)用中越來(lái)越受到青睞。
在實(shí)際應(yīng)用中,經(jīng)常需要將度分秒格式的坐標(biāo)轉(zhuǎn)換為十進(jìn)制度,以便于進(jìn)行計(jì)算和數(shù)據(jù)處理。例如,在GIS軟件中,地圖的坐標(biāo)系統(tǒng)可能需要統(tǒng)一為十進(jìn)制度以提高計(jì)算效率;在航海和航空領(lǐng)域,雖然傳統(tǒng)上使用度分秒,但在與現(xiàn)代導(dǎo)航系統(tǒng)集成時(shí),也需要轉(zhuǎn)換為十進(jìn)制度。因此,掌握度分秒到十進(jìn)制度的轉(zhuǎn)換方法對(duì)于相關(guān)領(lǐng)域的專(zhuān)業(yè)人士來(lái)說(shuō)是一項(xiàng)必備技能。
本文將介紹如何使用Java編程語(yǔ)言實(shí)現(xiàn)度分秒坐標(biāo)到十進(jìn)制度的轉(zhuǎn)換。我們將從坐標(biāo)轉(zhuǎn)換的基本概念入手,詳細(xì)闡述轉(zhuǎn)換的數(shù)學(xué)原理,并提供一個(gè)簡(jiǎn)潔、高效的Java實(shí)現(xiàn)方案。通過(guò)實(shí)際代碼示例,展示如何在Java中處理度分秒格式的字符串,將其分解為度、分、秒,并計(jì)算出對(duì)應(yīng)的十進(jìn)制度數(shù)值。此外,我們還將討論可能遇到的一些常見(jiàn)問(wèn)題,如精度處理和異常情況的處理,并提供解決方案。
通過(guò)閱讀本文,讀者將能夠理解度分秒和十進(jìn)制度之間的轉(zhuǎn)換原理,并掌握使用Java進(jìn)行坐標(biāo)轉(zhuǎn)換的實(shí)用技能。這不僅有助于提高讀者在GIS、導(dǎo)航等領(lǐng)域的專(zhuān)業(yè)能力,也為處理地理坐標(biāo)數(shù)據(jù)提供了一個(gè)強(qiáng)有力的工具。隨著地理信息技術(shù)的不斷發(fā)展,掌握這些基本技能將變得越來(lái)越重要。
一、度分秒的使用場(chǎng)景
在介紹度分秒的坐標(biāo)向十進(jìn)制度之前,我們首先來(lái)看看度分秒位置表示的使用場(chǎng)景。坐標(biāo)位置點(diǎn)是用來(lái)確定地球表面上一個(gè)特定地點(diǎn)的地理坐標(biāo)系統(tǒng)。這些坐標(biāo)通常以經(jīng)度和緯度來(lái)表示,它們可以以不同的格式表達(dá),包括度分秒(DMS)和十進(jìn)制度(DD)。
1、表示方法
度分秒是一種傳統(tǒng)的表示地理坐標(biāo)的方式,它將角度分為度、分和秒。
- 度(Degree):地球圓周被分為360度,每度進(jìn)一步分為60分。
- 分(Minute):每一度被分為60分,每分等于1/60度。
- 秒(Second):每一分被分為60秒,每秒等于1/60分。
在度分秒格式中,一個(gè)坐標(biāo)點(diǎn)可以表示為:度°分′秒″。例如,一個(gè)坐標(biāo)點(diǎn)可以寫(xiě)作 50°16′36″N(北緯50度16分36秒)和 68°1′12″W(西經(jīng)68度1分12秒)。眾所周知,與度分秒不同的還有經(jīng)緯度的表達(dá)方式。十進(jìn)制度是一種更現(xiàn)代的表示地理坐標(biāo)的方式,它直接以小數(shù)形式表示角度。在十進(jìn)制度格式中,一個(gè)坐標(biāo)點(diǎn)可以表示為:度.分。例如,上述的50°46′36″可以表示為50.2676667°。
2、兩者的轉(zhuǎn)換方法
將度分秒轉(zhuǎn)換為十進(jìn)制度,可以使用以下公式:
十進(jìn)制度=度+分/60+秒/(60*60),將上面的50°16′36″的位置轉(zhuǎn)為經(jīng)緯度位置計(jì)算過(guò)程為:50+16/60+36/3600=50+0.266666+0.01=50.26766。而轉(zhuǎn)換后的值就是我們可以直接在一些前端組件或者后端應(yīng)用中直接使用的值。
3、區(qū)別及使用場(chǎng)景
兩者的區(qū)別:
精確度:十進(jìn)制度可以提供更高的精確度,因?yàn)樗梢员硎镜叫?shù)點(diǎn)后很多位。易讀性:度分秒格式對(duì)于非專(zhuān)業(yè)人士來(lái)說(shuō)可能更直觀,因?yàn)樗M了傳統(tǒng)的測(cè)量方式。 計(jì)算:在進(jìn)行地理計(jì)算時(shí),十進(jìn)制度通常更方便,因?yàn)樗苊饬硕?、分、秒之間的轉(zhuǎn)換。
應(yīng)用場(chǎng)景
航海和航空:由于歷史原因,航海和航空領(lǐng)域仍然廣泛使用度分秒格式。地圖和GIS:現(xiàn)代地圖制作和地理信息系統(tǒng)(GIS)通常使用十進(jìn)制度,因?yàn)樗c計(jì)算機(jī)系統(tǒng)兼容性更好。科學(xué)和工程:在需要高精度的科學(xué)和工程領(lǐng)域,十進(jìn)制度是首選。在航海的應(yīng)用方面,我們經(jīng)常在海事局的官方網(wǎng)站上看到的都是度分秒的坐標(biāo)形式。
新設(shè)32 HAO DUN虛擬AIS航標(biāo),位置: 24-30.88N 118-14.20E;MMSI: 994136577;航標(biāo)類(lèi)型:東方位標(biāo);發(fā)射模式:自主連續(xù);播發(fā)間隔:3分鐘。
新設(shè)33 HAO DUN虛擬AIS航標(biāo),位置:24-30.89N 118-14.25E;MMSI: 994126460;航標(biāo)類(lèi)型:西方位標(biāo);發(fā)射模式:自主連續(xù);播發(fā)間隔:3分鐘。
請(qǐng)過(guò)往船舶注意
二、Java代碼轉(zhuǎn)換的實(shí)現(xiàn)
Java作為一種廣泛使用的編程語(yǔ)言,以其跨平臺(tái)性、高性能和豐富的庫(kù)支持,在處理地理坐標(biāo)轉(zhuǎn)換方面具有天然優(yōu)勢(shì)。通過(guò)Java實(shí)現(xiàn)度分秒到十進(jìn)制度的轉(zhuǎn)換,不僅可以提高開(kāi)發(fā)效率,還可以保證轉(zhuǎn)換過(guò)程的準(zhǔn)確性和可靠性。此外,Java的面向?qū)ο筇匦允沟棉D(zhuǎn)換程序易于維護(hù)和擴(kuò)展,便于集成到更復(fù)雜的系統(tǒng)中。因此本小節(jié)將重點(diǎn)介紹如何使用Java來(lái)實(shí)現(xiàn)度分秒和十進(jìn)制度的轉(zhuǎn)換。
1、確定計(jì)算值的符號(hào)
眾所周知,在地理系統(tǒng)中,緯度有南緯和北緯;經(jīng)度有東經(jīng)和西經(jīng)的區(qū)別。這是一個(gè)360度組成的球形。因此我們?cè)谶M(jìn)行坐標(biāo)計(jì)算的時(shí)候,要考慮這種天然的位置符號(hào)關(guān)系。比如在表示西經(jīng)100度時(shí),用十進(jìn)制數(shù)表達(dá)時(shí)就需要添加一個(gè)負(fù)號(hào)。而東經(jīng)是不需要的。然而,可能用來(lái)表示東經(jīng)和北緯的除了用英文的模式,還可能使用英文的模式,即N、W、E、S等。由于標(biāo)注習(xí)慣的不同,有的用戶(hù)或者系統(tǒng)喜歡把標(biāo)注符號(hào)放在前面,也有喜歡標(biāo)注在后面。這些都是可以的。但是要想實(shí)現(xiàn)統(tǒng)一的坐標(biāo)轉(zhuǎn)換,我們要可以識(shí)別上述的標(biāo)志,能在最終的結(jié)果中進(jìn)行符號(hào)的添加。
為了實(shí)現(xiàn)上面的需求,我們先來(lái)定義兩個(gè)字符串?dāng)?shù)字。一個(gè)是正數(shù)的經(jīng)緯度標(biāo)識(shí)字符串,另外一個(gè)是負(fù)數(shù)的經(jīng)緯度標(biāo)識(shí)字符串。代碼如下所示:
private static final String [] LAT_LON = {"E","N","東經(jīng)","北緯"};//正常經(jīng)緯度單位 private static final String [] NEGATIVE_LAT_LON = {"W","S","西經(jīng)","南緯"}; // 需要轉(zhuǎn)為負(fù)數(shù)的經(jīng)緯度單位
在進(jìn)行字符轉(zhuǎn)換時(shí),尤其是負(fù)號(hào)的數(shù)值轉(zhuǎn)換時(shí),我們首先需要判斷在傳入的坐標(biāo)位置中包含了標(biāo)識(shí)符,代碼如下:
/** * - 檢查經(jīng)緯度字符串中是否包含負(fù)數(shù)的坐標(biāo) * @param jwd * @return */ public static boolean checkFlag(String jwd) { if(StringUtils.isEmpty(jwd)) { return false; } boolean result = false; for(String sign : NEGATIVE_LAT_LON) { int index = jwd.trim().indexOf(sign); if(index >= 0) { result = true; break; } } return result; }
2、數(shù)值的清洗
在經(jīng)過(guò)經(jīng)緯度的數(shù)值符號(hào)計(jì)算之后,就可以將這些標(biāo)記字符串去掉,只保留下來(lái)需要分割計(jì)算的具體度分秒值。數(shù)據(jù)清洗的方法簡(jiǎn)單,循環(huán)我們的正常經(jīng)緯度標(biāo)記數(shù)組和負(fù)數(shù)經(jīng)緯度數(shù)組,最后再替換標(biāo)準(zhǔn)的冒號(hào)和非標(biāo)準(zhǔn)的冒號(hào)。得到最終清洗之后的字符串就是我們清洗之后的值。
/** * - 經(jīng)緯度數(shù)據(jù)清洗 * @param jwd * @return */ public static String jwdClearn(String jwd) { if(StringUtils.isEmpty(jwd)) { return jwd; } String result = jwd; //循環(huán)進(jìn)行正數(shù)據(jù)處理 for(String sign : LAT_LON) { result = result.replace(sign, ""); } //循環(huán)進(jìn)行負(fù)數(shù)據(jù)處理 for(String sign : NEGATIVE_LAT_LON) { result = result.replace(sign, ""); } result = result.replace(":", "").replace(":", ""); return result; }
3、度分秒轉(zhuǎn)換
掌握了數(shù)值符號(hào)的判定和數(shù)據(jù)清洗之后,下面就可以對(duì)清洗之后的數(shù)值進(jìn)行坐標(biāo)轉(zhuǎn)換。轉(zhuǎn)換的計(jì)算方法就是第一節(jié)中提到的計(jì)算方法。本身沒(méi)有很難的實(shí)現(xiàn)邏輯,因此在這里不進(jìn)行詳細(xì)的介紹。直接貼出實(shí)現(xiàn)的代碼,最后返回的值之前,需要根據(jù)符號(hào)的判斷,返回對(duì)應(yīng)的值。
/** * -經(jīng)緯度轉(zhuǎn)化,度分秒轉(zhuǎn)度. * -如:108°13′21″= 108.2225 * @param jwd * @return */ public static String DmsTurnDD(String jwd) { boolean negativeSign = false; if (Strings.isNotEmpty(jwd) && (jwd.contains("°"))) {//如果不為空并且存在度單位 //負(fù)數(shù)標(biāo)記 negativeSign = checkFlag(jwd); //計(jì)算前進(jìn)行數(shù)據(jù)處理 //jwd = jwd.replace("E", "").replace("N", "").replace(":", "").replace(":", ""); jwd = jwdClearn(jwd); double d = 0, m = 0, s = 0; d = Double.parseDouble(jwd.split("°")[0]); //不同單位的分,可擴(kuò)展 if (jwd.contains("′")) {//正常的′ m = Double.parseDouble(jwd.split("°")[1].split("′")[0]); } else if (jwd.contains("'")) {//特殊的' m = Double.parseDouble(jwd.split("°")[1].split("'")[0]); } //不同單位的秒,可擴(kuò)展 if (jwd.contains("″")) {//正常的″ //有時(shí)候沒(méi)有分 如:112°10.25″ s = jwd.contains("′") ? Double.parseDouble(jwd.split("′")[1].split("″")[0]) : Double.parseDouble(jwd.split("°")[1].split("″")[0]); } else if (jwd.contains("''")) {//特殊的'' //有時(shí)候沒(méi)有分 如:112°10.25'' s = jwd.contains("'") ? Double.parseDouble(jwd.split("'")[1].split("''")[0]) : Double.parseDouble(jwd.split("°")[1].split("''")[0]); } jwd = String.valueOf(d + m / 60 + s / 60 / 60);//計(jì)算并轉(zhuǎn)換為string } return negativeSign ? "-" + jwd : jwd; }
4、轉(zhuǎn)換實(shí)例
為了驗(yàn)證上述的度分秒坐標(biāo)是否正確的進(jìn)行了轉(zhuǎn)換,下面我們來(lái)編寫(xiě)測(cè)試代碼。測(cè)試不同的度分秒坐標(biāo)轉(zhuǎn)為十進(jìn)制坐標(biāo)的方法。我們分別將經(jīng)緯度的標(biāo)記寫(xiě)成中文和英文的都有,同時(shí)在具體的度分秒值的前面和后面都有。以此來(lái)測(cè)試程序的穩(wěn)定性和可靠性。
public static void main(String[] args) { List<String> latlonList = new ArrayList<String>(); latlonList.add("北緯15°08.1′"); latlonList.add("東經(jīng)117°50.9′"); latlonList.add("北緯15°07.4′"); latlonList.add("東經(jīng)117°50.8′"); latlonList.add("33°25'4.68\"S"); latlonList.add("15°08.1′南緯"); latlonList.add("117°50.9′西經(jīng)"); latlonList.add("東經(jīng)117°50.8′"); latlonList.add("南緯15°08.1′"); latlonList.add("W15°08.1′"); latlonList.add("E15°08.1′"); latlonList.add("65°08.1′N(xiāo)"); latlonList.add("68°08.1′"); latlonList.add("115°51.9′"); latlonList.add("25°15′26\"N"); latlonList.add("120°29′20\"E"); latlonList.add("24°50′30\"N"); latlonList.add("E120°05′45\""); latlonList.add("25°04′32\"N"); latlonList.add("119°51′22\"E"); latlonList.add("S25°28′12\""); latlonList.add("W120°14′30\""); latlonList.add("50°16′36″"); for(String latlon : latlonList) { System.out.println(latlon + "\t===>\t" +CoordinateUtil.DmsTurnDD(latlon)); } }
接下來(lái)在程序控制臺(tái)中看一下轉(zhuǎn)換的輸出結(jié)果。
可以看到所有的度分秒坐標(biāo)均已經(jīng)正常的進(jìn)行轉(zhuǎn)換,同時(shí)你可以使用計(jì)算機(jī)進(jìn)行驗(yàn)證計(jì)算結(jié)果是否正確。
三、總結(jié)
本文將介紹如何使用Java編程語(yǔ)言實(shí)現(xiàn)度分秒坐標(biāo)到十進(jìn)制度的轉(zhuǎn)換。我們將從坐標(biāo)轉(zhuǎn)換的基本概念入手,詳細(xì)闡述轉(zhuǎn)換的數(shù)學(xué)原理,并提供一個(gè)簡(jiǎn)潔、高效的Java實(shí)現(xiàn)方案。通過(guò)實(shí)際代碼示例,展示如何在Java中處理度分秒格式的字符串,將其分解為度、分、秒,并計(jì)算出對(duì)應(yīng)的十進(jìn)制度數(shù)值。
到此這篇關(guān)于Java實(shí)現(xiàn)度分秒坐標(biāo)轉(zhuǎn)十進(jìn)制度的文章就介紹到這了,更多相關(guān)Java度分秒坐標(biāo)轉(zhuǎn)十進(jìn)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java通過(guò)SSH連接路由器輸入命令并讀取響應(yīng)的操作方法
最近需要讀取和修改華為路由器的配置,使用Java語(yǔ)言開(kāi)發(fā),通過(guò)SSH連接,輸入命令并讀取響應(yīng),接下來(lái)通過(guò)本文給大家介紹下Java通過(guò)SSH連接路由器,輸入命令并讀取響應(yīng),需要的朋友可以參考下2024-01-01Spring?Boot提高開(kāi)發(fā)效率必備工具lombok使用
這篇文章主要為大家介紹了Spring?Boot提高開(kāi)發(fā)效率的必備工具lombok使用方法示例及步驟說(shuō)明,有需要的朋友可以借鑒參考下,希望能夠有所幫助2022-03-03Idea連接數(shù)據(jù)庫(kù)并執(zhí)行SQL語(yǔ)句的方法示例
這篇文章主要介紹了Idea連接數(shù)據(jù)庫(kù)并執(zhí)行SQL語(yǔ)句的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11詳解java中繼承關(guān)系類(lèi)加載順序問(wèn)題
這篇文章主要介紹了詳解java中繼承關(guān)系類(lèi)加載順序問(wèn)題的相關(guān)資料,需要的朋友可以參考下2017-06-06Javaweb 鼠標(biāo)移入移出表格顏色變化的實(shí)現(xiàn)
這篇文章主要介紹了Javaweb 鼠標(biāo)移入移出表格顏色變化的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09解讀Java中打印輸出對(duì)象內(nèi)容為什么可以不寫(xiě).toString()
這篇文章主要介紹了解讀Java中打印輸出對(duì)象內(nèi)容為什么可以不寫(xiě).toString()問(wèn)題,具有很的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09SpringCloud中的Eureka注冊(cè)中心詳細(xì)解讀
這篇文章主要介紹了SpringCloud中的Eureka注冊(cè)中心詳細(xì)解讀,想要參與服務(wù)注冊(cè)發(fā)現(xiàn)的實(shí)例首先需要向Eureka服務(wù)器注冊(cè)信息,注冊(cè)在第一次心跳發(fā)生時(shí)提交,需要的朋友可以參考下2023-11-11