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定位,所以需要加入相应的权限:

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345

推荐阅读更多精彩内容