高德地图定位相关

本文介绍AMapUtils中的定位监听与两点间距离计算方法。解析了如何通过AMapLocationListener实现定位更新,以及如何根据不同的定位类型和精度进行业务逻辑判断。同时,提供了计算两点间地理距离的具体算法。
摘要由CSDN通过智能技术生成

AMapUtils有一些计算测量相关的工具方法

/**
 * (官方)计算两点之间的距离(米)
 */
public static float calculateLineDistance(double lat1, double lng1, double lat2, double lng2) {
    lng1 *= 0.01745329251994329D;
    lat1 *= 0.01745329251994329D;
    lng2 *= 0.01745329251994329D;
    lat2 *= 0.01745329251994329D;
    double var12 = Math.sin(lng1);
    double var14 = Math.sin(lat1);
    double var16 = Math.cos(lng1);
    double var18 = Math.cos(lat1);
    double var20 = Math.sin(lng2);
    double var22 = Math.sin(lat2);
    double var24 = Math.cos(lng2);
    double var26 = Math.cos(lat2);
    double[] var28 = new double[3];
    double[] var29 = new double[3];
    var28[0] = var18 * var16;
    var28[1] = var18 * var12;
    var28[2] = var14;
    var29[0] = var26 * var24;
    var29[1] = var26 * var20;
    var29[2] = var22;
    double var30 = Math.sqrt((var28[0] - var29[0]) * (var28[0] - var29[0]) + (var28[1] - var29[1]) * (var28[1] - var29[1]) + (var28[2] - var29[2]) * (var28[2] - var29[2]));
    return (float)(Math.asin(var30 / 2.0D) * 1.27420015798544E7D);
}
/**
 * 定位监听
 */
private final AMapLocationListener mAmapLocationListener = new AMapLocationListener() {
    @Override
    public void onLocationChanged(AMapLocation location) {
        if (location != null) {
            //在开发时根据定位类型(通过AMapLocation类的getLocationType())进行定位点过滤,例如定位类型为6(基站定位)的点不进行业务运算。
            //根据设备获取的基站信息实现定位,基站定位精度一般不受使用环境影响,主要和基站的覆盖半径有关。
            //基站精度在500米-5公里之间,视所处区域运营商基站覆盖范围而定,会返回相应的地址描述
            //在开发时根据精度(通过AMapLocation类的getAccuracy()方法获取)进行定位点过滤,例如精度大于10米的点不进行业务运算。
            //0 定位失败
            //请通过AMapLocation.getErrorCode()方法获取错误码,并参考错误码对照表进行问题排查。

            //1 GPS定位结果
            //通过设备GPS定位模块返回的定位结果,精度较高,在10米-100米左右

            //2 前次定位结果
            //网络定位请求低于1秒、或两次定位之间设备位置变化非常小时返回,设备位移通过传感器感知。

            //4 缓存定位结果
            //返回一段时间前设备在同样的位置缓存下来的网络定位结果

            //5 Wifi定位结果
            //属于网络定位,定位精度相对基站定位会更好,定位精度较高,在5米-200米之间。

            //6 基站定位结果
            //纯粹依赖移动、联通、电信等移动网络定位,定位精度在500米-5000米之间。

            // errCode等于0代表定位成功,其他的为定位失败,具体的可以参照官网定位错误码说明
            if (location.getErrorCode() == 0 && location.getLocationType() != 0) {
                float accuracy = location.getAccuracy();
                if (accuracy > 600 || location.getTrustedLevel() != AMapLocation.TRUSTED_LEVEL_HIGH) {
                    // 定位偏差超过600米或者基站定位,使用旧的定位数据
                    Lg.d(TAG, "定位偏差超过600米或者可信度低");
                    copyGpsBean();
                } else {
                    if (mLastValidLocationMillis == -1) {
                        mLastLat = location.getLatitude();
                        mLastLng = location.getLongitude();
                        mLastValidLocationMillis = System.currentTimeMillis();
                    }

                    LocationUtils.printLog(location);
                    // 如果11分钟之内,位置偏移大于正常人步行11分钟的路程,就忽略
                    float distance = LocationUtils.calculateLineDistance(mLastLat, mLastLng, location.getLatitude(), location.getLongitude());

                    long duration = System.currentTimeMillis() - mLastValidLocationMillis;
                    Lg.d(TAG, "两次真实定位直线距离(米):" + distance + ", 时间间隔(秒):" + duration/1000);
                    Lg.d(TAG, "坐标类型:" + location.getCoordType());
                    //Lg.d(TAG, "可信度(高1,中2,低3,差4):" + location.getTrustedLevel());

                    if ((duration < FILTER_DURATION_MOVING) && (distance > FILTER_DISTANCE_MOVING) && mLocationTime > MIN_LOCATION_TIME) {
                        Lg.d(TAG, "这是一个严重漂移的定位数据");
                        copyGpsBean();
                    } else {
                        if (mLocationTime < MIN_LOCATION_TIME) {
                            mLocationTime++;
                        }
                        Lg.d(TAG, "这是一个有效定位");
                        mLastLat = location.getLatitude();
                        mLastLng = location.getLongitude();
                        mLastValidLocationMillis = System.currentTimeMillis();

                        mLocationData = new LocationData();
                        mLocationData.setLatitude(location.getLatitude());
                        mLocationData.setLongitude(location.getLongitude());
                        mLocationData.setAltitude(location.getAltitude());
                        mLocationData.setSpeed(location.getSpeed());
                        mLocationData.setTime(System.currentTimeMillis());
                        mLocationData.setAccuracy(location.getAccuracy());
                        mLocationData.setAddress(location.getAddress() + RxConstants.EMPTY_STR);
                        mLocationData.setLocationType(location.getLocationType());
                    }
                }
            } else {
                // 定位失败
                String result = "定位失败" + "\n" +
                        "错误码:" + location.getErrorCode() + "\n" +
                        "错误信息:" + location.getErrorInfo() + "\n" +
                        "错误描述:" + location.getLocationDetail() + "\n";
                Lg.e(TAG + result + "");
                copyGpsBean();
            }
        } else {
            Lg.e(TAG + " 定位失败,loc is null");
            copyGpsBean();
        }

        TaskManager.getInstance().setLastLocationData(mLocationData);
        if (mCallback != null) {
            mCallback.onLocationResult();
            mCallback = null;
        }
    }

    private void copyGpsBean() {
        if (mLocationData == null) {
            Lg.e("从没有获取过位置");
            return;
        }
        LocationData oldLocationData = mLocationData;
        mLocationData = new LocationData();
        mLocationData.setLatitude(oldLocationData.getLatitude());
        mLocationData.setLongitude(oldLocationData.getLongitude());
        mLocationData.setAltitude(oldLocationData.getAltitude());
        mLocationData.setSpeed(oldLocationData.getSpeed());
        mLocationData.setTime(System.currentTimeMillis());
        mLocationData.setAccuracy(oldLocationData.getAccuracy());
        mLocationData.setAddress(oldLocationData.getAddress() + RxConstants.EMPTY_STR);
        mLocationData.setLocationType(oldLocationData.getLocationType());
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ithouse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值