经纬度采用度分秒记录其实就是六十进制,采用小数形式一般就是十进制。以下就是实现六十进制与十进制之间的相互转换。
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)根据原理,程序的实现方式就比较简单了。以下是源代码。
-
-
- import java.math.BigDecimal;
- public class ConvertLatlng {
- //经纬度度分秒转换为小数
- public double convertToDecimal(double du,double fen,double miao){
- if(du<0)
- return -(Math.abs(du)+(Math.abs(fen)+(Math.abs(miao)/60))/60);
- return Math.abs(du)+(Math.abs(fen)+(Math.abs(miao)/60))/60;
- }
- //以字符串形式输入经纬度的转换
- public double convertToDecimalByString(String latlng){
- double du=Double.parseDouble(latlng.substring(0, latlng.indexOf("°")));
- double fen=Double.parseDouble(latlng.substring(latlng.indexOf("°")+1, latlng.indexOf("′")));
- double miao=Double.parseDouble(latlng.substring(latlng.indexOf("′")+1, latlng.indexOf("″")));
- if(du<0)
- return -(Math.abs(du)+(fen+(miao/60))/60);
- return du+(fen+(miao/60))/60;
- }
- //将小数转换为度分秒
- public String convertToSexagesimal(double num){
- int du=(int)Math.floor(Math.abs(num)); //获取整数部分
- double temp=getdPoint(Math.abs(num))*60;
- int fen=(int)Math.floor(temp); //获取整数部分
- double miao=getdPoint(temp)*60;
- if(num<0)
- return "-"+du+"°"+fen+"′"+miao+"″";
- return du+"°"+fen+"′"+miao+"″";
- }
- //获取小数部分
- public double getdPoint(double num){
- double d = num;
- int fInt = (int) d;
- BigDecimal b1 = new BigDecimal(Double.toString(d));
- BigDecimal b2 = new BigDecimal(Integer.toString(fInt));
- double dPoint = b1.subtract(b2).floatValue();
- return dPoint;
- }
- public static void main(String[] args) {
- ConvertLatlng convert=new ConvertLatlng();
- double latlng1=convert.convertToDecimal(37, 25, 19.222);
- double latlng2=convert.convertToDecimalByString("-37°25′19.222″");
- String latlng3=convert.convertToSexagesimal(121.084095);
- String latlng4=convert.convertToSexagesimal(-121.084095);
- System.out.println("转换小数(数字参数)"+latlng1);
- System.out.println("转换小数(字符串参数)"+latlng2);
- System.out.println("转换度分秒:"+latlng3);
- System.out.println("转换度分秒:"+latlng4);
- }
- }
-
复制代码4.Android程序的实现
其实用android实现经纬度进制的转换才是写这篇文章的初衷。所以写了一个Android客户端的软件,如图-1所示。
这样的软件可能使用性不大,于是添加了一些小功能进去,例如添加复制转换结果,根据当前位置获取经纬度并转换十进制或六十进制。
图-1 android实现经纬度转换的界面
主要功能并不复杂,都是基本的控件使用,代码中也有注解。以下是源代码。
1.ConvertLatlngActivity.java
-
-
- import java.math.BigDecimal;
- import android.app.Activity;
- import android.content.Context;
- import android.location.Criteria;
- import android.location.Location;
- import android.location.LocationListener;
- import android.location.LocationManager;
- import android.os.Bundle;
- import android.text.ClipboardManager;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.TextView;
- import android.widget.Toast;
- public class ConvertLatlngActivity extends Activity {
- /** Called when the activity is first created. */
- TextView result;
- EditText du;
- EditText fen;
- EditText miao;
- Button decimal;
- EditText latlng;
- Button sexagesimal;
- Button copy;
- Button bydecimal;
- Button bySexagesimal;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- result=(TextView)findViewById(R.id.result);
- du=(EditText)findViewById(R.id.du);
- fen=(EditText)findViewById(R.id.fen);
- miao=(EditText)findViewById(R.id.miao);
- //转换十进制
- decimal=(Button)findViewById(R.id.to_decimal);
- decimal.setOnClickListener(decimalClick);
- latlng=(EditText)findViewById(R.id.latlng);
- //转换六十进制
- sexagesimal=(Button)findViewById(R.id.to_sexagesimal);
- sexagesimal.setOnClickListener(sexagesimalClick);
- //复制结果
- copy=(Button)findViewById(R.id.copy);
- copy.setOnClickListener(copyClick);
- //获取十进制经纬度
- bydecimal=(Button)findViewById(R.id.by_decimal);
- bydecimal.setOnClickListener(byDecimalClick);
- //获取六十进制经纬度
- bySexagesimal=(Button)findViewById(R.id.by_sexagesimal);
- bySexagesimal.setOnClickListener(bySexagesimalClick);
- }
- //转换十进制事件响应
- OnClickListener decimalClick=new OnClickListener() {
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- String dStr=du.getText().toString();
- String fStr=fen.getText().toString();
- String mStr=miao.getText().toString();
- if(dStr==null||dStr.equals("")){
- Toast.makeText(v.getContext(), "The du number is empty!", Toast.LENGTH_SHORT).show();
- du.requestFocus();
- }else if(fStr==null||fStr.equals("")){
- Toast.makeText(v.getContext(), "The fen number is empty!", Toast.LENGTH_SHORT).show();
- fen.requestFocus();
- }else if(mStr==null||mStr.equals("")){
- Toast.makeText(v.getContext(), "The miao number is empty!", Toast.LENGTH_SHORT).show();
- miao.requestFocus();
- }else{
- double d_du=Double.parseDouble(du.getText().toString());
- double d_fen=Double.parseDouble(fen.getText().toString());
- double d_miao=Double.parseDouble(miao.getText().toString());
- String rs=String.valueOf(convertToDecimal(d_du, d_fen, d_miao));
- result.setText(rs);
- }
- }
- };
- //转换六十进制时间响应
- OnClickListener sexagesimalClick=new OnClickListener() {
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- String s=latlng.getText().toString();
- if(s==null||s.equals("")){
- Toast.makeText(v.getContext(), "The number is empty!", Toast.LENGTH_SHORT).show();
- latlng.requestFocus();
- }
- else{
- double num=Double.parseDouble(latlng.getText().toString());
- result.setText(convertToSexagesimal(num));
- }
- }
- };
- //复制
- OnClickListener copyClick=new OnClickListener() {
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- ClipboardManager clip = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);
- clip.setText(result.getText().toString());
- }
- };
- //获取十进制经纬度
- OnClickListener byDecimalClick=new OnClickListener() {
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- Location location=getCurrentLocation();
- if(location!=null){
- double lat=location.getLatitude();
- double lng=location.getLongitude();
- result.setText("Latitude:"+lat+"\nLongitude:"+lng);
- }else{
- //没有定位
- Toast.makeText(v.getContext(), "No position!", Toast.LENGTH_SHORT).show();
- }
- }
- };
- //获取六十进制经纬度
- OnClickListener bySexagesimalClick=new OnClickListener() {
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- Location location=getCurrentLocation();
- if(location!=null){
- double lat=location.getLatitude();
- double lng=location.getLongitude();
- result.setText("Latitude:"+convertToSexagesimal(lat)+
- "\nLongitude:"+convertToSexagesimal(lng));
- }else{
- //没有定位
- Toast.makeText(v.getContext(), "No position!", Toast.LENGTH_SHORT).show();
- }
- }
- };
- private Location getCurrentLocation(){
- LocationManager loctionManager;
- String contextService=Context.LOCATION_SERVICE;
- //通过系统服务,取得LocationManager对象
- loctionManager=(LocationManager) getSystemService(contextService);
- Criteria criteria = new Criteria();
- criteria.setAccuracy(Criteria.ACCURACY_FINE);//高精度
- criteria.setAltitudeRequired(false);//不要求海拔
- criteria.setBearingRequired(false);//不要求方位
- criteria.setCostAllowed(true);//允许有花费
- criteria.setPowerRequirement(Criteria.POWER_LOW);//低功耗
- //从可用的位置提供器中,匹配以上标准的最佳提供器
- String provider = loctionManager.getBestProvider(criteria, true);
- //获得最后一次变化的位置
- Location location = loctionManager.getLastKnownLocation(provider);
- //监听位置变化,2秒一次,距离10米以上
- loctionManager.requestLocationUpdates(provider, 2000, 10, locationListener);
- return location;
- }
- //位置监听器 空实现
- private final LocationListener locationListener = new LocationListener() {
- @Override
- public void onStatusChanged(String provider, int status, Bundle extras) {
- }
- @Override
- public void onProviderEnabled(String provider) {
- }
- @Override
- public void onProviderDisabled(String provider) {
- }
- //当位置变化时触发
- @Override
- public void onLocationChanged(Location location) {
- }
- };
- //经纬度度分秒转换为小数
- public double convertToDecimal(double du,double fen,double miao){
- if(du<0)
- return -(Math.abs(du)+(Math.abs(fen)+(Math.abs(miao)/60))/60);
- return Math.abs(du)+(Math.abs(fen)+(Math.abs(miao)/60))/60;
- }
- //将小数转换为度分秒
- public String convertToSexagesimal(double num){
- int du=(int)Math.floor(Math.abs(num)); //获取整数部分
- double temp=getdPoint(Math.abs(num))*60;
- int fen=(int)Math.floor(temp); //获取整数部分
- double miao=getdPoint(temp)*60;
- if(num<0)
- return "-"+du+"°"+fen+"′"+miao+"″";
- return du+"°"+fen+"′"+miao+"″";
- }
- //获取小数部分
- public double getdPoint(double num){
- double d = num;
- int fInt = (int) d;
- BigDecimal b1 = new BigDecimal(Double.toString(d));
- BigDecimal b2 = new BigDecimal(Integer.toString(fInt));
- double dPoint = b1.subtract(b2).floatValue();
- return dPoint;
- }
- }
-
复制代码2.main.xml
-
-
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="Result:"
- android:layout_marginTop="12dip"/>
- <TextView android:id="@+id/result"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text=""
- android:layout_marginTop="12dip"/>
- <LinearLayout android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:layout_marginTop="12dip">
- <EditText android:id="@+id/du"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:singleLine="true"
- android:numeric="signed"/>
- <TextView android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="度(°)"
- android:layout_weight="1"
- android:paddingLeft="6dip"/>
- <EditText android:id="@+id/fen"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:singleLine="true"
- android:numeric="integer"/>
- <TextView android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="分(′)"
- android:layout_weight="1"
- android:paddingLeft="6dip"/>
- <EditText android:id="@+id/miao"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:singleLine="true"
- android:imeOptions="actionDone"
- android:numeric="decimal"/>
- <TextView android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="秒(″)"
- android:layout_weight="1"
- android:paddingLeft="6dip"/>
- </LinearLayout>
- <Button android:id="@+id/to_decimal"
- android:layout_width="112dip"
- android:layout_height="wrap_content"
- android:text="toDecimal"
- android:layout_marginTop="12dip"/>
- <LinearLayout android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:layout_marginTop="12dip">
- <TextView android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="经纬度(Lat/Lng):"
- android:paddingRight="6dip"/>
- <EditText android:id="@+id/latlng"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:singleLine="true"
- android:inputType="numberSigned|numberDecimal"/>
- </LinearLayout>
- <LinearLayout android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:layout_marginTop="12dip">
- <Button android:id="@+id/to_sexagesimal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="toSexagesimal"
- android:layout_marginTop="6dip"/>
- <Button android:id="@+id/copy"
- android:layout_width="112dip"
- android:layout_height="wrap_content"
- android:text="copy Result"
- android:layout_marginTop="6dip"/>
- </LinearLayout>
- <Button android:id="@+id/by_decimal"
- android:layout_width="224dip"
- android:layout_height="wrap_content"
- android:text="current location by decimal"
- android:layout_marginTop="6dip"/>
- <Button android:id="@+id/by_sexagesimal"
- android:layout_width="224dip"
- android:layout_height="wrap_content"
- android:text="current location by sexagesimal"
- android:layout_marginTop="6dip"/>
- </LinearLayout>
-
复制代码下面是数字键盘的一些属性:
android:numeric=”decimal” 允许输入十进制数字,但不能输入负数,显示数字键盘;
android:numeric=”signed” 只允许输入整数,包括负整数,显示数字键盘;
android:numeric=”integer” 只允许输入正整数,显示数字键盘;
android:inputType=”numberSigned|numberDecimal” 允许输入十进制,包括负数,显示数字键盘;
android:digits=”1234567890.+-*/% ()” 只允许输入里面定义的字符,不验证是否为数字,如可以输入如”–11.23–“,键盘显示常规输入键盘。
因为使用了GPS定位,所以需要加入相应的权限:
-
-
- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
-
复制代码