Android 常用的地球經緯度轉換公里(km)計算工具類
阿新 • • 發佈:2018-12-19
地球赤道上環繞地球一週走一圈共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不在這裡介紹,自行去百度定位官方檢視;