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不在这里介绍,自行去百度定位官方查看;


 

目录
相关文章
|
7月前
|
前端开发 定位技术 Android开发
Android平台GB28181设备接入端如何实时更新经纬度实现国标平台侧电子地图位置标注
我们在做GB28181设备接入端的时候,其中有个功能,不难但非常重要:那就是GB28181实时位置的订阅(mobileposition subscribe)和上报(notify)。
115 0
|
7月前
|
XML Android开发 数据格式
Android GB28181接入端实时位置订阅和上报之-如何获取当前经纬度
我们在做Android平台GB28181的时候,其中实时位置(MobilePosition)订阅和上报这块,涉及到实时经纬度的获取,特别是执法记录、车载系统的那个等场景,几乎就是标配。
|
编解码 文件存储 Android开发
Android | 如何计算图片占用内存的大小
Android | 如何计算图片占用内存的大小
Android | 如何计算图片占用内存的大小
|
数据安全/隐私保护 Android开发
Android为图片添加水印,裁剪图片,旋转图片工具类
Android为图片添加水印,裁剪图片,旋转图片工具类
142 0
|
Java 定位技术 Android开发
安卓(JAVA)已知两点经纬度,求出一条线上定距(比如隔20米或30一个点)的经纬度。
安卓(JAVA)已知两点经纬度,求出一条线上定距(比如隔20米或30一个点)的经纬度。
234 0
|
Java Android开发
安卓(JAVA)已知两点经纬度,求出一条线上几等分的点的经纬度。
安卓(JAVA)已知两点经纬度,求出一条线上几等分的点的经纬度。
83 0
|
定位技术 API Android开发
安卓基于百度地图计算两个经纬度点的直线距离并只保留两位小数
安卓基于百度地图计算两个经纬度点的直线距离并只保留两位小数
312 0
Java&Android像素px、dip转换工具类
Java&Android像素px、dip转换工具类
326 0
|
Android开发
Android WIFI是否连接,网络状态监测工具类
Android WIFI是否连接,网络状态监测工具类
270 0
Java&Android获取当前日期、时间、星期几、获取指定格式的日期时间、时间戳工具类包含使用示例
Java&Android获取当前日期、时间、星期几、获取指定格式的日期时间、时间戳工具类包含使用示例
583 0
Java&Android获取当前日期、时间、星期几、获取指定格式的日期时间、时间戳工具类包含使用示例