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)

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

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


android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

android:layout_height="wrap_content"

android:text="Result:"

android:layout_marginTop="12dip"/>

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text=""

android:layout_marginTop="12dip"/>

android:layout_height="wrap_content"

android:orientation="horizontal"

android:layout_marginTop="12dip">

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_weight="1"

android:singleLine="true"

android:numeric="signed"/>

android:layout_height="wrap_content"

android:text="度(°)"

android:layout_weight="1"

android:paddingLeft="6dip"/>

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_weight="1"

android:singleLine="true"

android:numeric="integer"/>

android:layout_height="wrap_content"

android:text="分(′)"

android:layout_weight="1"

android:paddingLeft="6dip"/>

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_weight="1"

android:singleLine="true"

android:imeOptions="actionDone"

android:numeric="decimal"/>

android:layout_height="wrap_content"

android:text="秒(″)"

android:layout_weight="1"

android:paddingLeft="6dip"/>

android:layout_width="112dip"

android:layout_height="wrap_content"

android:text="toDecimal"

android:layout_marginTop="12dip"/>

android:layout_height="wrap_content"

android:orientation="horizontal"

android:layout_marginTop="12dip">

android:layout_height="wrap_content"

android:text="经纬度(Lat/Lng):"

android:paddingRight="6dip"/>

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:singleLine="true"

android:inputType="numberSigned|numberDecimal"/>

android:layout_height="wrap_content"

android:orientation="horizontal"

android:layout_marginTop="12dip">

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="toSexagesimal"

android:layout_marginTop="6dip"/>

android:layout_width="112dip"

android:layout_height="wrap_content"

android:text="copy Result"

android:layout_marginTop="6dip"/>

android:layout_width="224dip"

android:layout_height="wrap_content"

android:text="current location by decimal"

android:layout_marginTop="6dip"/>

android:layout_width="224dip"

android:layout_height="wrap_content"

android:text="current location by sexagesimal"

android:layout_marginTop="6dip"/>


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

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

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

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

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

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

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

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容