Android 常用的地球经纬度转换公里(km)计算工具类

简介: 地球赤道上环绕地球一周走一圈共40075.04公里,而@一圈分成360°,而每1°(度)有60,每一度一秒在赤道上的长度计算如下:   40075.

地球赤道上环绕地球一周走一圈共40075.04公里,而@一圈分成360°,而每1°(度)有60,每一度一秒在赤道上的长度计算如下:   40075.04km/360°=111.31955km   

111.31955km/60=1.8553258km=1855.3m

任意两点距离计算公式见代码:

package org.wavefar.lib.utils;

import android.content.Context;

import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.navi.BaiduMapAppNotSupportNaviException;
import com.baidu.mapapi.navi.BaiduMapNavigation;
import com.baidu.mapapi.navi.NaviParaOption;
import com.baidu.mapapi.utils.poi.BaiduMapPoiSearch;
import com.baidu.mapapi.utils.route.BaiduMapRoutePlan;
import com.baidu.mapsdkplatform.comapi.location.CoordinateType;

import org.wavefar.lib.utils.LogUtil;
import org.wavefar.lib.utils.StringUtil;

/**
 * 定位相关工具类
 * @author summer
 */
public class LocationUtil {

	private LocationClient  mLocationClient;
	private BDAbstractLocationListener mlistener;
	private Context context;
    // 地球半径
	private final static double EARTH_RADIUS = 6378.137;
	public LocationUtil(Context context) {
		 this.context = context;
		 mLocationClient = new LocationClient(context.getApplicationContext());
	     LocationClientOption option = initLocationOption();
	     mLocationClient.setLocOption(option);
	     LogUtil.d(LocationUtil.class.getSimpleName(), "当前定位库版本" + mLocationClient.getVersion());
	}

	private LocationClientOption initLocationOption() {
		LocationClientOption option = new LocationClientOption();
        // 设置定位模式
		option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        // 返回的定位结果是百度经纬度,默认值gcj02
		option.setCoorType(CoordinateType.BD09LL);
        // 设置发起定位请求的间隔时间为5000ms
		option.setScanSpan(5000);
        // 返回的定位结果包含地址信息
		option.setIsNeedAddress(true);
        //可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
		option.setIsNeedLocationPoiList(true);
        // 返回的定位结果包含手机机头的方向
		option.setNeedDeviceDirect(true);
        //可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
        option.setIsNeedLocationDescribe(true);
        option.setOpenGps(true);
		return option;
	}
	
	/**
	 * 注册定位回调
	 * @param listener
	 */
	public void registerLocationListener(BDAbstractLocationListener listener) {
		mlistener = listener;
		if (mlistener != null) {
            mLocationClient.registerLocationListener(mlistener);
        }
	}
	
    /**
     * 启动定位
     */
    public void start() {
        if (mLocationClient.isStarted()) {
            return;
        }
        mLocationClient.start();
    }

    /**
     * 重新定位
     */
    public void reStart() {
        if (mLocationClient.isStarted()) {
            return;
        }
        mLocationClient.restart();
    }

    /**
     * 停止定位
     */
    public void stop() {
        if (mLocationClient.isStarted()) {
            mLocationClient.stop();
        }
    }
	
    /**
     * 销毁定位
     */
    public void destroy() {
        if (mLocationClient != null) {
            mLocationClient.unRegisterLocationListener(mlistener);
            mLocationClient.stop();
            mLocationClient = null;
        }
    }
    
    /**
     * 启动百度地图导航(Native),如果本地没有安装百度地图,调用WEBAPP
     * @param pt1 起点
     * @param pt2 终点
     */
    public void startNavi(LatLng pt1, LatLng pt2) {
        // 构建 导航参数
        NaviParaOption para = new NaviParaOption()
                .startPoint(pt1).endPoint(pt2);
        try {
            BaiduMapNavigation.openBaiduMapNavi(para, context);
        } catch (BaiduMapAppNotSupportNaviException e) {
            BaiduMapNavigation.openWebBaiduMapNavi(para, context);
            e.printStackTrace();
        }
    }

    /**
     * 启动百度地图导航(Web)
     */
    public void startWebNavi(LatLng pt1,LatLng pt2) {
        NaviParaOption para = new NaviParaOption()
                .startPoint(pt1).endPoint(pt2);
        BaiduMapNavigation.openWebBaiduMapNavi(para, context);
    }
    
    /**
     * 用完导航后需要调用该函数销毁
     */
    public void stopNavi() {
	   try {
           BaiduMapNavigation.finish(context);
           BaiduMapRoutePlan.finish(context);
           BaiduMapPoiSearch.finish(context);
       } catch (Exception e) {
           e.printStackTrace();
       }
    }
    
    private static double rad(double d) {
        return d * Math.PI / 180.0;
    }

    /**
     * 计算距离 返回单位km
     * @param lat1
     * @param lng1
     * @param lat2
     * @param lng2
     * @return
     */
    public static double getDistance(double lat1, double lng1, double lat2,
                                     double lng2) {
        LogUtil.d("LocationUtil", "lat1:" + lat1 + "lng1:" + lng1 + "lat2:" + lat2 + "lng2:" + lng2);
        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        // 如果有一方等于零,直接返回0
        if (radLat1 == 0 || radLat2 == 0) {
            return 0;
        }
        double a = radLat1 - radLat2;
        double b = rad(lng1) - rad(lng2);
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
                + Math.cos(radLat1) * Math.cos(radLat2)
                * Math.pow(Math.sin(b / 2), 2)));
        s = s * EARTH_RADIUS;
        s = Math.round(s * 10000) / 10000;
        return s;
    }

    /**
     * 距离格式化
     *
     * @param distance 以千米为单位
     * @return
     */
    public static String distanceKMFormat(double distance) {
        return distance > 1 ? (distance + "KM") : (distance * 1000 + "M");
    }


    /**
     * 距离只保留两位小数
     * @param distance 以米为单位
     * @return
     */
    public static String distanceFormat(double distance) {
        String str;
        double value = distance;
        if (distance >= 1000) {
            value = value / 1000;
            str = "KM";
        } else {
            str = "M";
        }
        return String.format("%s%s",StringUtil.formatDecimal(value,null),str);
    }
    
}

 以上代码定位依赖于百度定位API,所以粘贴以上代码之前,需要引入百度定位API,引入百度定位API不在这里介绍,自行去百度定位官方查看;


 

目录
相关文章
|
3月前
|
自然语言处理 定位技术 API
Android经典实战之如何获取图片的经纬度以及如何根据经纬度获取对应的地点名称
本文介绍如何在Android中从图片提取地理位置信息并转换为地址。首先利用`ExifInterface`获取图片内的经纬度,然后通过`Geocoder`将经纬度转为地址。注意操作需在子线程进行且考虑多语言支持。
234 4
|
5月前
|
Android开发
Android WindowManager工具类
Android WindowManager工具类
44 0
|
6月前
|
JSON Java 定位技术
【Android App】GPS获取定位经纬度和根据经纬度获取详细地址讲解及实战(附源码和演示 超详细)
【Android App】GPS获取定位经纬度和根据经纬度获取详细地址讲解及实战(附源码和演示 超详细)
1905 0
|
前端开发 定位技术 Android开发
Android平台GB28181设备接入端如何实时更新经纬度实现国标平台侧电子地图位置标注
我们在做GB28181设备接入端的时候,其中有个功能,不难但非常重要:那就是GB28181实时位置的订阅(mobileposition subscribe)和上报(notify)。
173 0
|
XML Android开发 数据格式
Android GB28181接入端实时位置订阅和上报之-如何获取当前经纬度
我们在做Android平台GB28181的时候,其中实时位置(MobilePosition)订阅和上报这块,涉及到实时经纬度的获取,特别是执法记录、车载系统的那个等场景,几乎就是标配。
132 0
|
编解码 文件存储 Android开发
Android | 如何计算图片占用内存的大小
Android | 如何计算图片占用内存的大小
Android | 如何计算图片占用内存的大小
|
并行计算 算法 Java
RenderScript 让你的Android计算速度快的飞上天!
RenderScript 让你的Android计算速度快的飞上天!
RenderScript 让你的Android计算速度快的飞上天!
Java&Android获取当前日期、时间、星期几、获取指定格式的日期时间、时间戳工具类包含使用示例
Java&Android获取当前日期、时间、星期几、获取指定格式的日期时间、时间戳工具类包含使用示例
713 0
Java&Android获取当前日期、时间、星期几、获取指定格式的日期时间、时间戳工具类包含使用示例
|
数据安全/隐私保护 Android开发
Android为图片添加水印,裁剪图片,旋转图片工具类
Android为图片添加水印,裁剪图片,旋转图片工具类
175 0
|
Java 定位技术 Android开发
安卓(JAVA)已知两点经纬度,求出一条线上定距(比如隔20米或30一个点)的经纬度。
安卓(JAVA)已知两点经纬度,求出一条线上定距(比如隔20米或30一个点)的经纬度。
274 0
下一篇
无影云桌面