android 经纬度度分秒与十进制之间的相互转换

经纬度采用度分秒记录其实就是六十进制,采用小数形式一般就是十进制。以下就是实现六十进制与十进制之间的相互转换。


1.怎么把经纬度十进制单位转换成标准的度分秒单位计算公式是,十进制的经度,纬度数的整数部分就是度数(°),小数部分乘以60得到的数取整数部分就是分数(′),再用该数的小数部分乘以60就是秒数(″)。如一个经度的十进制为:117.121806,那么:
   第一步:度数(°)117°,
   第二步:分数(′)7′(0.121806×60=7.308360189199448,取整数部分为7),

   第三步:秒数(″)18.501611351966858″(0.30836018919944763×60=18.501611351966858),即度分秒为117°7′18.501611351966858″。


2.怎么把经纬度度分秒单位转换成十进制单位

将度分秒转换为十进制则刚好相反,将秒数(″)除以60,得到的数就是分数(′)的小数部分,将该小数加上分数(′)整数部

分就是整个分数(′),再将该分数(′)除以60,得到的小数就是度数(°)的小数部分,在加上度数的整数部分就是经纬度的十进制形式。例如,将一个纬度为37°25′19.222″的六十进制转换为十进制的步骤为:

第一步(对应上面的第三步):19.222/60=0.3203666666666667,0.3203666666666667为分数(′)的小数部分,

第二步(对应上面的第二步):25+0.3203666666666667=25.3203666666666667,25.3203666666666667分数(′)

第三步(对应上面的第一步):25.3203666666666667/60=0.4220061111111111,0.4220061111111111为度数(°)的小数部分

37°25′19.222″转换的最终结果为37+0.4220061111111111=37.4220061111111111


3.程序实现(java)

根据原理,程序的实现方式就比较简单了。以下是源代码。


      1. import java.math.BigDecimal;

      2. public class ConvertLatlng {

      3. //经纬度度分秒转换为小数
      4. public double convertToDecimal(double du,double fen,double miao){
      5. if(du<0)
      6. return -(Math.abs(du)+(Math.abs(fen)+(Math.abs(miao)/60))/60);

      7. return Math.abs(du)+(Math.abs(fen)+(Math.abs(miao)/60))/60;

      8. }
      9. //以字符串形式输入经纬度的转换
      10. public double convertToDecimalByString(String latlng){

      11. double du=Double.parseDouble(latlng.substring(0, latlng.indexOf("°")));
      12. double fen=Double.parseDouble(latlng.substring(latlng.indexOf("°")+1, latlng.indexOf("′")));
      13. double miao=Double.parseDouble(latlng.substring(latlng.indexOf("′")+1, latlng.indexOf("″")));
      14. if(du<0)
      15. return -(Math.abs(du)+(fen+(miao/60))/60);
      16. return du+(fen+(miao/60))/60;

      17. }

      18. //将小数转换为度分秒
      19. public String convertToSexagesimal(double num){

      20. int du=(int)Math.floor(Math.abs(num));    //获取整数部分
      21. double temp=getdPoint(Math.abs(num))*60;
      22. int fen=(int)Math.floor(temp); //获取整数部分
      23. double miao=getdPoint(temp)*60;
      24. if(num<0)
      25. return "-"+du+"°"+fen+"′"+miao+"″";

      26. return du+"°"+fen+"′"+miao+"″";

      27. }
      28. //获取小数部分
      29. public double getdPoint(double num){
      30. double d = num;
      31. int fInt = (int) d;
      32. BigDecimal b1 = new BigDecimal(Double.toString(d));
      33. BigDecimal b2 = new BigDecimal(Integer.toString(fInt));
      34. double dPoint = b1.subtract(b2).floatValue();
      35. return dPoint;
      36. }

      37. public static void main(String[] args) {

      38. ConvertLatlng convert=new ConvertLatlng();
      39. double latlng1=convert.convertToDecimal(37, 25, 19.222);
      40. double latlng2=convert.convertToDecimalByString("-37°25′19.222″");
      41. String latlng3=convert.convertToSexagesimal(121.084095);
      42. String latlng4=convert.convertToSexagesimal(-121.084095);

      43. System.out.println("转换小数(数字参数)"+latlng1);
      44. System.out.println("转换小数(字符串参数)"+latlng2);
      45. System.out.println("转换度分秒:"+latlng3);
      46. System.out.println("转换度分秒:"+latlng4);

      47. }

      48. }
复制代码

4.Android程序的实现

其实用android实现经纬度进制的转换才是写这篇文章的初衷。所以写了一个Android客户端的软件,如图-1所示。

这样的软件可能使用性不大,于是添加了一些小功能进去,例如添加复制转换结果,根据当前位置获取经纬度并转换十进制或六十进制。


图-1 android实现经纬度转换的界面

主要功能并不复杂,都是基本的控件使用,代码中也有注解。以下是源代码。

1.ConvertLatlngActivity.java
      1. import java.math.BigDecimal;

      2. import android.app.Activity;
      3. import android.content.Context;
      4. import android.location.Criteria;
      5. import android.location.Location;
      6. import android.location.LocationListener;
      7. import android.location.LocationManager;
      8. import android.os.Bundle;
      9. import android.text.ClipboardManager;
      10. import android.view.View;
      11. import android.view.View.OnClickListener;
      12. import android.widget.Button;
      13. import android.widget.EditText;
      14. import android.widget.TextView;
      15. import android.widget.Toast;

      16. public class ConvertLatlngActivity extends Activity {
      17. /** Called when the activity is first created. */

      18. TextView result;

      19. EditText du;
      20. EditText fen;
      21. EditText miao;
      22. Button decimal;

      23. EditText latlng;
      24. Button sexagesimal;

      25. Button copy;
      26. Button bydecimal;
      27. Button bySexagesimal;

      28. @Override
      29. public void onCreate(Bundle savedInstanceState) {
      30. super.onCreate(savedInstanceState);
      31. setContentView(R.layout.main);

      32. result=(TextView)findViewById(R.id.result);

      33. du=(EditText)findViewById(R.id.du);
      34. fen=(EditText)findViewById(R.id.fen);
      35. miao=(EditText)findViewById(R.id.miao);
      36. //转换十进制
      37. decimal=(Button)findViewById(R.id.to_decimal);
      38. decimal.setOnClickListener(decimalClick);

      39. latlng=(EditText)findViewById(R.id.latlng);
      40. //转换六十进制
      41. sexagesimal=(Button)findViewById(R.id.to_sexagesimal);
      42. sexagesimal.setOnClickListener(sexagesimalClick);

      43. //复制结果
      44. copy=(Button)findViewById(R.id.copy);
      45. copy.setOnClickListener(copyClick);

      46. //获取十进制经纬度
      47. bydecimal=(Button)findViewById(R.id.by_decimal);
      48. bydecimal.setOnClickListener(byDecimalClick);

      49. //获取六十进制经纬度
      50. bySexagesimal=(Button)findViewById(R.id.by_sexagesimal);
      51. bySexagesimal.setOnClickListener(bySexagesimalClick);
      52. }
      53. //转换十进制事件响应
      54. OnClickListener decimalClick=new OnClickListener() {

      55. @Override
      56. public void onClick(View v) {
      57. // TODO Auto-generated method stub

      58. String dStr=du.getText().toString();
      59. String fStr=fen.getText().toString();
      60. String mStr=miao.getText().toString();
      61. if(dStr==null||dStr.equals("")){
      62. Toast.makeText(v.getContext(), "The du number is empty!", Toast.LENGTH_SHORT).show();
      63. du.requestFocus();

      64. }else if(fStr==null||fStr.equals("")){
      65. Toast.makeText(v.getContext(), "The fen number is empty!", Toast.LENGTH_SHORT).show();
      66. fen.requestFocus();

      67. }else if(mStr==null||mStr.equals("")){
      68. Toast.makeText(v.getContext(), "The miao number is empty!", Toast.LENGTH_SHORT).show();
      69. miao.requestFocus();

      70. }else{
      71. double d_du=Double.parseDouble(du.getText().toString());
      72. double d_fen=Double.parseDouble(fen.getText().toString());
      73. double d_miao=Double.parseDouble(miao.getText().toString());
      74. String rs=String.valueOf(convertToDecimal(d_du, d_fen, d_miao));
      75. result.setText(rs);
      76. }
      77. }
      78. };
      79. //转换六十进制时间响应
      80. OnClickListener sexagesimalClick=new OnClickListener() {

      81. @Override
      82. public void onClick(View v) {
      83. // TODO Auto-generated method stub
      84. String s=latlng.getText().toString();
      85. if(s==null||s.equals("")){
      86. Toast.makeText(v.getContext(), "The number is empty!", Toast.LENGTH_SHORT).show();
      87. latlng.requestFocus();

      88. }
      89. else{
      90. double num=Double.parseDouble(latlng.getText().toString());
      91. result.setText(convertToSexagesimal(num));
      92. }
      93. }
      94. };

      95. //复制
      96. OnClickListener copyClick=new OnClickListener() {

      97. @Override
      98. public void onClick(View v) {
      99. // TODO Auto-generated method stub
      100. ClipboardManager clip = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);
      101. clip.setText(result.getText().toString());
      102. }
      103. };

      104. //获取十进制经纬度
      105. OnClickListener byDecimalClick=new OnClickListener() {

      106. @Override
      107. public void onClick(View v) {
      108. // TODO Auto-generated method stub
      109. Location location=getCurrentLocation();
      110. if(location!=null){
      111. double lat=location.getLatitude();
      112. double lng=location.getLongitude();
      113. result.setText("Latitude:"+lat+"\nLongitude:"+lng);
      114. }else{
      115. //没有定位
      116. Toast.makeText(v.getContext(), "No position!", Toast.LENGTH_SHORT).show();
      117. }
      118. }
      119. };

      120. //获取六十进制经纬度
      121. OnClickListener bySexagesimalClick=new OnClickListener() {

      122. @Override
      123. public void onClick(View v) {
      124. // TODO Auto-generated method stub
      125. Location location=getCurrentLocation();
      126. if(location!=null){
      127. double lat=location.getLatitude();
      128. double lng=location.getLongitude();
      129. result.setText("Latitude:"+convertToSexagesimal(lat)+
      130. "\nLongitude:"+convertToSexagesimal(lng));
      131. }else{
      132. //没有定位
      133. Toast.makeText(v.getContext(), "No position!", Toast.LENGTH_SHORT).show();
      134. }
      135. }
      136. };

      137. private Location getCurrentLocation(){

      138. LocationManager loctionManager;
      139. String contextService=Context.LOCATION_SERVICE;
      140. //通过系统服务,取得LocationManager对象
      141. loctionManager=(LocationManager) getSystemService(contextService);
      142. Criteria criteria = new Criteria();
      143. criteria.setAccuracy(Criteria.ACCURACY_FINE);//高精度
      144. criteria.setAltitudeRequired(false);//不要求海拔
      145. criteria.setBearingRequired(false);//不要求方位
      146. criteria.setCostAllowed(true);//允许有花费
      147. criteria.setPowerRequirement(Criteria.POWER_LOW);//低功耗

      148. //从可用的位置提供器中,匹配以上标准的最佳提供器
      149. String provider = loctionManager.getBestProvider(criteria, true);
      150. //获得最后一次变化的位置
      151. Location location = loctionManager.getLastKnownLocation(provider);
      152. //监听位置变化,2秒一次,距离10米以上
      153. loctionManager.requestLocationUpdates(provider, 2000, 10, locationListener);

      154. return location;
      155. }

      156. //位置监听器 空实现
      157. private final LocationListener locationListener = new LocationListener() {
      158. @Override
      159. public void onStatusChanged(String provider, int status, Bundle extras) {
      160. }
      161. @Override
      162. public void onProviderEnabled(String provider) {
      163. }
      164. @Override
      165. public void onProviderDisabled(String provider) {
      166. }
      167. //当位置变化时触发
      168. @Override
      169. public void onLocationChanged(Location location) {

      170. }
      171. };

      172. //经纬度度分秒转换为小数
      173. public double convertToDecimal(double du,double fen,double miao){

      174. if(du<0)
      175. return -(Math.abs(du)+(Math.abs(fen)+(Math.abs(miao)/60))/60);

      176. return Math.abs(du)+(Math.abs(fen)+(Math.abs(miao)/60))/60;

      177. }
      178. //将小数转换为度分秒
      179. public String convertToSexagesimal(double num){

      180. int du=(int)Math.floor(Math.abs(num));    //获取整数部分
      181. double temp=getdPoint(Math.abs(num))*60;
      182. int fen=(int)Math.floor(temp); //获取整数部分
      183. double miao=getdPoint(temp)*60;
      184. if(num<0)
      185. return "-"+du+"°"+fen+"′"+miao+"″";

      186. return du+"°"+fen+"′"+miao+"″";

      187. }
      188. //获取小数部分
      189. public double getdPoint(double num){
      190. double d = num;
      191. int fInt = (int) d;
      192. BigDecimal b1 = new BigDecimal(Double.toString(d));
      193. BigDecimal b2 = new BigDecimal(Integer.toString(fInt));
      194. double dPoint = b1.subtract(b2).floatValue();
      195. return dPoint;
      196. }

      197. }
复制代码
2.main.xml
      1. <?xml version="1.0" encoding="utf-8"?>
      2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      3. android:orientation="vertical"
      4. android:layout_width="fill_parent"
      5. android:layout_height="fill_parent"
      6. >
      7. <TextView android:layout_width="fill_parent"
      8. android:layout_height="wrap_content"
      9. android:text="Result:"
      10. android:layout_marginTop="12dip"/>
      11. <TextView  android:id="@+id/result"
      12. android:layout_width="fill_parent"
      13. android:layout_height="wrap_content"
      14. android:text=""
      15. android:layout_marginTop="12dip"/>

      16. <LinearLayout android:layout_width="fill_parent"
      17. android:layout_height="wrap_content"
      18. android:orientation="horizontal"
      19. android:layout_marginTop="12dip">

      20. <EditText android:id="@+id/du"
      21. android:layout_width="fill_parent"
      22. android:layout_height="wrap_content"
      23. android:layout_weight="1"
      24. android:singleLine="true"
      25. android:numeric="signed"/>
      26. <TextView android:layout_width="fill_parent"
      27. android:layout_height="wrap_content"
      28. android:text="度(°)"
      29. android:layout_weight="1"
      30. android:paddingLeft="6dip"/>

      31. <EditText android:id="@+id/fen"
      32. android:layout_width="fill_parent"
      33. android:layout_height="wrap_content"
      34. android:layout_weight="1"
      35. android:singleLine="true"
      36. android:numeric="integer"/>
      37. <TextView android:layout_width="fill_parent"
      38. android:layout_height="wrap_content"
      39. android:text="分(′)"
      40. android:layout_weight="1"
      41. android:paddingLeft="6dip"/>

      42. <EditText android:id="@+id/miao"
      43. android:layout_width="fill_parent"
      44. android:layout_height="wrap_content"
      45. android:layout_weight="1"
      46. android:singleLine="true"
      47. android:imeOptions="actionDone"
      48. android:numeric="decimal"/>
      49. <TextView android:layout_width="fill_parent"
      50. android:layout_height="wrap_content"
      51. android:text="秒(″)"
      52. android:layout_weight="1"
      53. android:paddingLeft="6dip"/>

      54. </LinearLayout>

      55. <Button android:id="@+id/to_decimal"
      56. android:layout_width="112dip"
      57. android:layout_height="wrap_content"
      58. android:text="toDecimal"
      59. android:layout_marginTop="12dip"/>

      60. <LinearLayout android:layout_width="fill_parent"
      61. android:layout_height="wrap_content"
      62. android:orientation="horizontal"
      63. android:layout_marginTop="12dip">

      64. <TextView android:layout_width="wrap_content"
      65. android:layout_height="wrap_content"
      66. android:text="经纬度(Lat/Lng):"
      67. android:paddingRight="6dip"/>
      68. <EditText android:id="@+id/latlng"
      69. android:layout_width="fill_parent"
      70. android:layout_height="wrap_content"
      71. android:singleLine="true"
      72. android:inputType="numberSigned|numberDecimal"/>

      73. </LinearLayout>

      74. <LinearLayout android:layout_width="fill_parent"
      75. android:layout_height="wrap_content"
      76. android:orientation="horizontal"
      77. android:layout_marginTop="12dip">

      78. <Button android:id="@+id/to_sexagesimal"
      79. android:layout_width="wrap_content"
      80. android:layout_height="wrap_content"
      81. android:text="toSexagesimal"
      82. android:layout_marginTop="6dip"/>
      83. <Button android:id="@+id/copy"
      84. android:layout_width="112dip"
      85. android:layout_height="wrap_content"
      86. android:text="copy Result"
      87. android:layout_marginTop="6dip"/>

      88. </LinearLayout>

      89. <Button android:id="@+id/by_decimal"
      90. android:layout_width="224dip"
      91. android:layout_height="wrap_content"
      92. android:text="current location by decimal"
      93. android:layout_marginTop="6dip"/>

      94. <Button android:id="@+id/by_sexagesimal"
      95. android:layout_width="224dip"
      96. android:layout_height="wrap_content"
      97. android:text="current location by sexagesimal"
      98. android:layout_marginTop="6dip"/>

      99. </LinearLayout>
复制代码

下面是数字键盘的一些属性:

android:numeric=”decimal” 允许输入十进制数字,但不能输入负数,显示数字键盘;

android:numeric=”signed” 只允许输入整数,包括负整数,显示数字键盘;

android:numeric=”integer” 只允许输入正整数,显示数字键盘;

android:inputType=”numberSigned|numberDecimal”  允许输入十进制,包括负数,显示数字键盘;

android:digits=”1234567890.+-*/% ()” 只允许输入里面定义的字符,不验证是否为数字,如可以输入如”–11.23–“,键盘显示常规输入键盘。

因为使用了GPS定位,所以需要加入相应的权限:

      1. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值