Java实现度分秒坐标转十进制度
作者:夜郎king
前言
在地理信息系统(GIS)、导航、测绘等领域,精确地表示和转换地理位置坐标是一项基本而重要的任务。地理坐标通常以经度和纬度的形式表示,它们可以采用度分秒(DMS)或十进制度(DD)两种格式。度分秒是一种传统的表示方式,它将角度分为度、分和秒,而十进制度则以小数形式直接表示角度,更便于计算机处理。随着技术的发展,十进制度因其精确性和便捷性在现代应用中越来越受到青睐。
在实际应用中,经常需要将度分秒格式的坐标转换为十进制度,以便于进行计算和数据处理。例如,在GIS软件中,地图的坐标系统可能需要统一为十进制度以提高计算效率;在航海和航空领域,虽然传统上使用度分秒,但在与现代导航系统集成时,也需要转换为十进制度。因此,掌握度分秒到十进制度的转换方法对于相关领域的专业人士来说是一项必备技能。
本文将介绍如何使用Java编程语言实现度分秒坐标到十进制度的转换。我们将从坐标转换的基本概念入手,详细阐述转换的数学原理,并提供一个简洁、高效的Java实现方案。通过实际代码示例,展示如何在Java中处理度分秒格式的字符串,将其分解为度、分、秒,并计算出对应的十进制度数值。此外,我们还将讨论可能遇到的一些常见问题,如精度处理和异常情况的处理,并提供解决方案。
通过阅读本文,读者将能够理解度分秒和十进制度之间的转换原理,并掌握使用Java进行坐标转换的实用技能。这不仅有助于提高读者在GIS、导航等领域的专业能力,也为处理地理坐标数据提供了一个强有力的工具。随着地理信息技术的不断发展,掌握这些基本技能将变得越来越重要。
一、度分秒的使用场景
在介绍度分秒的坐标向十进制度之前,我们首先来看看度分秒位置表示的使用场景。坐标位置点是用来确定地球表面上一个特定地点的地理坐标系统。这些坐标通常以经度和纬度来表示,它们可以以不同的格式表达,包括度分秒(DMS)和十进制度(DD)。
1、表示方法
度分秒是一种传统的表示地理坐标的方式,它将角度分为度、分和秒。
- 度(Degree):地球圆周被分为360度,每度进一步分为60分。
- 分(Minute):每一度被分为60分,每分等于1/60度。
- 秒(Second):每一分被分为60秒,每秒等于1/60分。
在度分秒格式中,一个坐标点可以表示为:度°分′秒″。例如,一个坐标点可以写作 50°16′36″N(北纬50度16分36秒)和 68°1′12″W(西经68度1分12秒)。众所周知,与度分秒不同的还有经纬度的表达方式。十进制度是一种更现代的表示地理坐标的方式,它直接以小数形式表示角度。在十进制度格式中,一个坐标点可以表示为:度.分。例如,上述的50°46′36″可以表示为50.2676667°。
2、两者的转换方法
将度分秒转换为十进制度,可以使用以下公式:
十进制度=度+分/60+秒/(60*60),将上面的50°16′36″的位置转为经纬度位置计算过程为:50+16/60+36/3600=50+0.266666+0.01=50.26766。而转换后的值就是我们可以直接在一些前端组件或者后端应用中直接使用的值。
3、区别及使用场景
两者的区别:
精确度:十进制度可以提供更高的精确度,因为它可以表示到小数点后很多位。易读性:度分秒格式对于非专业人士来说可能更直观,因为它模拟了传统的测量方式。 计算:在进行地理计算时,十进制度通常更方便,因为它避免了度、分、秒之间的转换。
应用场景
航海和航空:由于历史原因,航海和航空领域仍然广泛使用度分秒格式。地图和GIS:现代地图制作和地理信息系统(GIS)通常使用十进制度,因为它与计算机系统兼容性更好。科学和工程:在需要高精度的科学和工程领域,十进制度是首选。在航海的应用方面,我们经常在海事局的官方网站上看到的都是度分秒的坐标形式。
新设32 HAO DUN虚拟AIS航标,位置: 24-30.88N 118-14.20E;MMSI: 994136577;航标类型:东方位标;发射模式:自主连续;播发间隔:3分钟。
新设33 HAO DUN虚拟AIS航标,位置:24-30.89N 118-14.25E;MMSI: 994126460;航标类型:西方位标;发射模式:自主连续;播发间隔:3分钟。
请过往船舶注意
二、Java代码转换的实现
Java作为一种广泛使用的编程语言,以其跨平台性、高性能和丰富的库支持,在处理地理坐标转换方面具有天然优势。通过Java实现度分秒到十进制度的转换,不仅可以提高开发效率,还可以保证转换过程的准确性和可靠性。此外,Java的面向对象特性使得转换程序易于维护和扩展,便于集成到更复杂的系统中。因此本小节将重点介绍如何使用Java来实现度分秒和十进制度的转换。
1、确定计算值的符号
众所周知,在地理系统中,纬度有南纬和北纬;经度有东经和西经的区别。这是一个360度组成的球形。因此我们在进行坐标计算的时候,要考虑这种天然的位置符号关系。比如在表示西经100度时,用十进制数表达时就需要添加一个负号。而东经是不需要的。然而,可能用来表示东经和北纬的除了用英文的模式,还可能使用英文的模式,即N、W、E、S等。由于标注习惯的不同,有的用户或者系统喜欢把标注符号放在前面,也有喜欢标注在后面。这些都是可以的。但是要想实现统一的坐标转换,我们要可以识别上述的标志,能在最终的结果中进行符号的添加。
为了实现上面的需求,我们先来定义两个字符串数字。一个是正数的经纬度标识字符串,另外一个是负数的经纬度标识字符串。代码如下所示:
private static final String [] LAT_LON = {"E","N","东经","北纬"};//正常经纬度单位 private static final String [] NEGATIVE_LAT_LON = {"W","S","西经","南纬"}; // 需要转为负数的经纬度单位
在进行字符转换时,尤其是负号的数值转换时,我们首先需要判断在传入的坐标位置中包含了标识符,代码如下:
/** * - 检查经纬度字符串中是否包含负数的坐标 * @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、数值的清洗
在经过经纬度的数值符号计算之后,就可以将这些标记字符串去掉,只保留下来需要分割计算的具体度分秒值。数据清洗的方法简单,循环我们的正常经纬度标记数组和负数经纬度数组,最后再替换标准的冒号和非标准的冒号。得到最终清洗之后的字符串就是我们清洗之后的值。
/** * - 经纬度数据清洗 * @param jwd * @return */ public static String jwdClearn(String jwd) { if(StringUtils.isEmpty(jwd)) { return jwd; } String result = jwd; //循环进行正数据处理 for(String sign : LAT_LON) { result = result.replace(sign, ""); } //循环进行负数据处理 for(String sign : NEGATIVE_LAT_LON) { result = result.replace(sign, ""); } result = result.replace(":", "").replace(":", ""); return result; }
3、度分秒转换
掌握了数值符号的判定和数据清洗之后,下面就可以对清洗之后的数值进行坐标转换。转换的计算方法就是第一节中提到的计算方法。本身没有很难的实现逻辑,因此在这里不进行详细的介绍。直接贴出实现的代码,最后返回的值之前,需要根据符号的判断,返回对应的值。
/** * -经纬度转化,度分秒转度. * -如:108°13′21″= 108.2225 * @param jwd * @return */ public static String DmsTurnDD(String jwd) { boolean negativeSign = false; if (Strings.isNotEmpty(jwd) && (jwd.contains("°"))) {//如果不为空并且存在度单位 //负数标记 negativeSign = checkFlag(jwd); //计算前进行数据处理 //jwd = jwd.replace("E", "").replace("N", "").replace(":", "").replace(":", ""); jwd = jwdClearn(jwd); double d = 0, m = 0, s = 0; d = Double.parseDouble(jwd.split("°")[0]); //不同单位的分,可扩展 if (jwd.contains("′")) {//正常的′ m = Double.parseDouble(jwd.split("°")[1].split("′")[0]); } else if (jwd.contains("'")) {//特殊的' m = Double.parseDouble(jwd.split("°")[1].split("'")[0]); } //不同单位的秒,可扩展 if (jwd.contains("″")) {//正常的″ //有时候没有分 如:112°10.25″ s = jwd.contains("′") ? Double.parseDouble(jwd.split("′")[1].split("″")[0]) : Double.parseDouble(jwd.split("°")[1].split("″")[0]); } else if (jwd.contains("''")) {//特殊的'' //有时候没有分 如: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);//计算并转换为string } return negativeSign ? "-" + jwd : jwd; }
4、转换实例
为了验证上述的度分秒坐标是否正确的进行了转换,下面我们来编写测试代码。测试不同的度分秒坐标转为十进制坐标的方法。我们分别将经纬度的标记写成中文和英文的都有,同时在具体的度分秒值的前面和后面都有。以此来测试程序的稳定性和可靠性。
public static void main(String[] args) { List<String> latlonList = new ArrayList<String>(); latlonList.add("北纬15°08.1′"); latlonList.add("东经117°50.9′"); latlonList.add("北纬15°07.4′"); latlonList.add("东经117°50.8′"); latlonList.add("33°25'4.68\"S"); latlonList.add("15°08.1′南纬"); latlonList.add("117°50.9′西经"); latlonList.add("东经117°50.8′"); latlonList.add("南纬15°08.1′"); latlonList.add("W15°08.1′"); latlonList.add("E15°08.1′"); latlonList.add("65°08.1′N"); 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)); } }
接下来在程序控制台中看一下转换的输出结果。
可以看到所有的度分秒坐标均已经正常的进行转换,同时你可以使用计算机进行验证计算结果是否正确。
三、总结
本文将介绍如何使用Java编程语言实现度分秒坐标到十进制度的转换。我们将从坐标转换的基本概念入手,详细阐述转换的数学原理,并提供一个简洁、高效的Java实现方案。通过实际代码示例,展示如何在Java中处理度分秒格式的字符串,将其分解为度、分、秒,并计算出对应的十进制度数值。
到此这篇关于Java实现度分秒坐标转十进制度的文章就介绍到这了,更多相关Java度分秒坐标转十进制内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!