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());
}
};