高德地图纠偏不准,祭出我自己的纠偏算法

高德地图纠偏不准,祭出我自己的纠偏算法

背景:

最近使用高德地图用来记录轨迹的运动距离,使用的是api中的


原始点359个点,在经过纠偏后得到了了两个点,如下所示,是我整段轨迹,红色点是纠偏之后高德地图给我的点。经过测试几次之后我对这个api有点失望了,决定自己写纠偏,然后再做距离求解。

                      

     


算法过程:

1.     我们的计算过程滞后运动过程,在经过点检验之后将有效点加入我们的距离计算过程。

2.     有效点的判断是根据与权重点的距离进行判断的。

3.     权重点的获取是通过前一个权威点与新的轨迹点根据一定权重得到的(一开始权威点选为首个轨迹点)

4.     轨迹的运行过程中,有效权重点只有一个,代表的是一段有效轨迹的稳定点,如果出现疑似偏移点的点,则再生成一个,代表新的这个疑似偏移点为开始的点的权重,如果这个新的疑似偏移点之后的5个点都没有偏移,则说明这段轨迹有效,则加入有效轨迹点中并更新权重点诶该点。

5.     权重点代表着一段轨迹的最终稳定点,当它代表的轨迹点数小于5个则表明那段点可能是偏移点。则要被干掉。

 


我们这里先选取全重为0.8。

w1= p1*0.2 + p2*0.8

 

下面探讨几中偏点的情况:

这里我们设置5个单位各自为可接受范围。超过5个格子就要弃点。每个格子代表单位时间2s。我们这里的定位间隔为2s。

起始点偏移在可接受范围:

我们通过权重点慢慢修复到正常的过程。绿色圈为各个定位时刻的权重点。

起始点偏移超过可接受范围:

起始超过很多单位格子为要过滤的偏移点。P1、p2为不可接受偏移点,但是在起始不知道,当p3出现之后,发现距离有点大,则为p3生成新的权重点w2,连续判断5个点没有偏差,说明这几个点的轨迹是正确的则采用,将w1代表的点干掉,并将w1更新到w2这里。

 

中间有段时间定为没有成功定位

因为没有成功定位所以被分隔的两段的定位都是有效数据

有一个偏点:

这里有一个跳点p5,判定为可疑跳点之后,我们给他一个新的权重点w2,在接下来判断中发现p6相对于w2来说也是跳点,则把w2代表的点干掉,然后重新让他代表p6。在接下来的5次定位稳定,则将权重点更新为w1。此时w1代表的是p1到当前定位点。

其他可能的偏移:

在有段时间失去坐标之后又重新获取,但是在判断的时候突然又有跳点,则我们只能按照算法舍去p6,从p8开始重新设置为新的记录点。

红色为计算的距离。

判断偏移点算法:

我们这里做的是车辆的轨迹记录,所以我们在判断偏移点的距离的时候按照车辆80km/h(22m/s)来计算的。则2s的定位间隔来算的话应该是下一个定位点距离权重点44m之外就算作偏移点。在有一段时间没有成功获取定位点的时候先计算两点间隔时间再计算最大偏移点范围。

流程图:


注意:在高德地图中如果位置没有改变的话,返回的是缓存定位结果,定位时间也是缓存的。所以说如果定位坐标不改变,那么定位时间不会改变

代码:

/**
     * @param
aMapLocation
    
* @return 是否获得有效点,需要存储和计算距离
     */
   
private BooleanfilterPos(AMapLocationaMapLocation) {

       
SimpleDateFormat df= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.CHINA);
       
Date date= new Date(aMapLocation.getTime());
       
String time= df.format(date);//定位时间
       
filterString =time + "开始虑点"+ "\r\n";

        try
{
           
// 获取的第一个定位点不进行过滤
           
if (isFirst) {
               
isFirst =false;
               
weight1.setLatitude(aMapLocation.getLatitude());
               
weight1.setLongitude(aMapLocation.getLongitude());
               
weight1.setTime(aMapLocation.getTime());
               
weight1.setSpeed(aMapLocation.getSpeed());

               
/****************存储数据到文件中,后面好分析******************/

               
filterString +="第一次定位"+ "\r\n";

               
/**********************************/

               
// 将得到的第一个点存储入w1的缓存集合
               
final TraceLocationtraceLocation =new TraceLocation();
               
traceLocation.setLatitude(aMapLocation.getLatitude());
                
traceLocation.setLongitude(aMapLocation.getLongitude());
               
traceLocation.setTime(aMapLocation.getTime());
               
traceLocation.setSpeed(aMapLocation.getSpeed());
               
w1TempList.add(traceLocation);
               
w1Count++;

                return true;

           
} else{
               
filterString +="非第一次定位"+ "\r\n";
               
// 过滤静止时的偏点,在静止时速度小于1米就算做静止状态
               
if (aMapLocation.getSpeed() <1) {
                   
return false;
               
}

               
/****************存储数据到文件中,后面好分析******************/
               
SimpleDateFormat df1= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.CHINA);
               
Date date1= new Date(aMapLocation.getTime());
               
String time1= df1.format(date1);// 定位时间
               
String testString=time1 + ":" + aMapLocation.getTime() +"_" + aMapLocation.getLocationType() +"," + aMapLocation.getLatitude() +"," + aMapLocation.getLongitude() +"," + aMapLocation.getAccuracy() +"," + aMapLocation.getSpeed() +"\r\n";
               
FileWriteUtil.getInstance().save("tutu_driver_true.txt",testString);

                if
(weight2== null) {
                   
filterString +="weight2 == null" +"\r\n";

                   
// 计算w1与当前定位点p1的时间差并得到最大偏移距离D
                   
long offsetTimeMils= aMapLocation.getTime() -weight1.getTime();
                    long
offsetTimes = (offsetTimeMils/ 1000);
                    long
MaxDistance =offsetTimes *CAR_MAX_SPEED;
                    float
distance =AMapUtils.calculateLineDistance(
                           
new LatLng(weight1.getLatitude(),weight1.getLongitude()),
                            new
LatLng(aMapLocation.getLatitude(),aMapLocation.getLongitude()));

                    
filterString +="distance = " +distance + ",MaxDistance =" +MaxDistance  +"\r\n";

                    if
(distance> MaxDistance) {
                       
filterString +="distance > MaxDistance" +"\r\n";
                       
// 将设置w2位新的点,并存储入w2临时缓存
                       
weight2 =new TraceLocation();
                       
weight2.setLatitude(aMapLocation.getLatitude());
                       
weight2.setLongitude(aMapLocation.getLongitude());
                       
weight2.setTime(aMapLocation.getTime());
                       
weight2.setSpeed(aMapLocation.getSpeed());

                       
w2TempList.add(weight2);

                        return false;

                   
} else{
                       
filterString +="distance < MaxDistance" +"\r\n";
                       
// p1加入到做坐标集合w1TempList
                       
TraceLocation traceLocation=new TraceLocation();
                       
traceLocation.setLatitude(aMapLocation.getLatitude());
                       
traceLocation.setLongitude(aMapLocation.getLongitude());
                       
traceLocation.setTime(aMapLocation.getTime());
                       
traceLocation.setSpeed(aMapLocation.getSpeed());
                       
w1TempList.add(traceLocation);
                       
w1Count++;

                        
// 更新w1权值点
                       
weight1.setLatitude(weight1.getLatitude() * 0.2 + aMapLocation.getLatitude() *0.8);
                       
weight1.setLongitude(weight1.getLongitude() * 0.2 + aMapLocation.getLongitude() *0.8);
                       
weight1.setTime(aMapLocation.getTime());
                       
weight1.setSpeed(aMapLocation.getSpeed());

                        if
(w1TempList.size() >3) {
                           
filterString += "d1TempList.size() > 3"+ "\r\n";
                            
// w1TempList中的数据放入finalList,并将w1TempList清空
                           
mListPoint.addAll(w1TempList);
                           
w1TempList.clear();
                            return true;
                       
} else{
                            
filterString += "d1TempList.size() < 3"+ "\r\n";
                            return false;
                       
}
                    }

                }
else {

                   
filterString +="weight2 != null" +"\r\n";
                    
// 计算w1与当前定位点p1的时间差并得到最大偏移距离D
                   
long offsetTimeMils= aMapLocation.getTime() -weight2.getTime();
                    long
offsetTimes = (offsetTimeMils/ 1000);
                    long
MaxDistance =offsetTimes *16;
                    float
distance =AMapUtils.calculateLineDistance(
                           
new LatLng(weight2.getLatitude(),weight2.getLongitude()),
                            new
LatLng(aMapLocation.getLatitude(),aMapLocation.getLongitude()));

                    
filterString+="distance= " +distance + ",MaxDistance = " +MaxDistance  +"\r\n";

                    if
(distance> MaxDistance) {
                       
filterString +="distance > MaxDistance" +"\r\n";
                       
w2TempList.clear();
                       
// 将设置w2位新的点,并存储入w2临时缓存
                       
weight2 =new TraceLocation();
                       
weight2.setLatitude(aMapLocation.getLatitude());
                       
weight2.setLongitude(aMapLocation.getLongitude());
                       
weight2.setTime(aMapLocation.getTime());
                       
weight2.setSpeed(aMapLocation.getSpeed());

                       
w2TempList.add(weight2);

                        return false;
                   
} else{
                        
filterString +="distance < MaxDistance" +"\r\n";

                       
// p1加入到做坐标集合w2TempList
                       
TraceLocation traceLocation=new TraceLocation();
                       
traceLocation.setLatitude(aMapLocation.getLatitude());
                       
traceLocation.setLongitude(aMapLocation.getLongitude());
                       
traceLocation.setTime(aMapLocation.getTime());
                       
traceLocation.setSpeed(aMapLocation.getSpeed());
                        
w2TempList.add(traceLocation);

                       
// 更新w2权值点
                       
weight2.setLatitude(weight2.getLatitude() * 0.2 + aMapLocation.getLatitude() *0.8);
                       
weight2.setLongitude(weight2.getLongitude() * 0.2 + aMapLocation.getLongitude() *0.8);
                       
weight2.setTime(aMapLocation.getTime());
                       
weight2.setSpeed(aMapLocation.getSpeed());

                        if
(w2TempList.size() >4) {
                            
filterString+="w2TempList.size()> 4" +"\r\n";
                           
// 判断w1所代表的定位点数是否>4,小于说明w1之前的点为从一开始就有偏移的点
                           
if (w1Count> 4) {
                               
filterString += "w1Count > 4" + "\r\n";
                                
mListPoint.addAll(w1TempList);
                           
} else{
                               
filterString += "w1Count < 4" + "\r\n";
                               
w1TempList.clear();
                           
}

                            
// w2TempList集合中数据放入finalList
                           
mListPoint.addAll(w2TempList);

                           
// 1、清空w2TempList集合 2、更新w1的权值点为w2的值 3、将w2置为null
                           
w2TempList.clear();
                           
weight1 =weight2;
                           
weight2 =null;
                            return true;

                       
} else{
                           
filterString += "w2TempList.size() > 4"+ "\r\n";
                            return false;
                       
}
                    }
                }
            }
        }
finally {
           
FileWriteUtil.getInstance().save("tutu_driver_filter.txt",filterString);
//           Log.d("hhh","finnaly");
       
}


    }

 

算法模拟验证:

这里的验证是基于上面讨论的几种可能的偏移点进行的。

正常轨迹

这段正常轨迹是通过虑点之后存储的可信点绘制的一串轨迹坐标。

         

 

起始点有偏点:

红色点是我手动让第一个点偏移了3km之后得到了偏移点,按照算法该点是被过滤了的

              

起点成功定位了3个点之后,因为一些外部原因,定位断了

这是模拟起始点成功定位,之后有段时间没有定位成功,过了很久才又定位成功的情况

                   

连续3点在一段有效范围之内就算做有效定位。

 

 

中间点有偏点

这里设定了第200个点是偏点,则出现之后过滤直接被过滤掉了

                

中间点是定位成功点:

模拟在运行到一半突然定位失效,然后有定位有效了5个点,然后又定位失效的,最后有有效的情况

设置了从200个点到205个点为一段有效的定位点。因为在5个点内这段定位没有被判偏,则视为有效定位

                 

 

测试、分析数据过程:

因为是时时定位没有办法,所以只能将原始点通过文件的方式存储起来。过滤之后的有效点通过json的形式存储在sp中。在分析数据时候借助excel进行数据整理和分析。

步骤:

1、在算法的每个关键步骤和判断加入String,记录此时的状态。在进行测试之后拿出文件进行分析,具体的文件拿出过程参考我的安卓文件存储与取出:

http://blog.csdn.net/u011486491/article/details/69257436

2、通过分析步骤之后确保算法大概的正确性。

3、通过算法获取有效的定位数据点并通过sp进行存储。

4、通过定时任务模拟运动过程,重现轨迹运行过程,这时候因为有了真实数据,我们就可以将文件存储的结果,变成log打印来分析。


5、通过改变真实数据的各个值去模拟我们可能遇到的偏移点

 

原始数据:


过滤后的数据:


定位过程流程数据:

 

 

 

从过滤数据导入excel的数据


 

 

测试用的activity的代码:

public class ShowLocationActivity extends BaseActivity implements TraceListener {

    MapView mMapView = null;
    //初始化地图控制器对象
    AMap aMap;
    ActivityShowLocationBinding mDataBinding;
    private List<TraceLocation> mListPoint = new ArrayList<>();
    private List<TraceLocation> originPosList;
    private LBSTraceClient lbsTraceClient;
    private Gson mGson = new Gson();

    final int CAR_MAX_SPEED = 22; // 80km/h
    private Boolean isFirst = true;         // 是否是第一次定位点
    private TraceLocation weight1 = new TraceLocation();        // 权重点1
    private TraceLocation weight2;                          // 权重点2
    private List<TraceLocation> w1TempList = new ArrayList<>();     // w1的临时定位点集合
    private List<TraceLocation> w2TempList = new ArrayList<>();     // w2的临时定位点集合
    private int w1Count = 0; // 统计w1Count所统计过的点数
    private String filterString;
    private int posCount = 0;
    private TraceLocation posTraceLocation;
    private int beginPos = 0;


    private final Timer timer = new Timer();

    TimerTask task = new TimerTask() {

        private MarkerOptions markerOption;

        @Override
        public void run() {
            runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    //处理延时任务
                    if (posCount == 200) {

                        // 创建跳点
                        TraceLocation traceLocation = originPosList.get(posCount);
                        LatLng latLng = new LatLng(traceLocation.getLatitude()+0.0160100, traceLocation.getLongitude() - 0.0160000);
                        traceLocation.setLatitude(latLng.latitude);
                        traceLocation.setLongitude(latLng.longitude);

                        // 绘制跳点
                        markerOption = new MarkerOptions();
                        markerOption.position(latLng);
                        markerOption.draggable(false);//设置Marker可拖动
                        markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory
                                .decodeResource(getResources(), R.mipmap.icon_red_point)));
                        // Marker设置为贴地显示,可以双指下拉地图查看效果
                        markerOption.setFlat(true);//设置marker平贴地图效果
                        aMap.addMarker(markerOption);

                        posTraceLocation = traceLocation;
                    }
                    else if (posCount == 201) {

                        // 创建跳点
                        TraceLocation traceLocation = originPosList.get(posCount);
                        LatLng latLng = new LatLng(traceLocation.getLatitude()+0.0160300, traceLocation.getLongitude() - 0.0160000);
                        traceLocation.setLatitude(latLng.latitude);
                        traceLocation.setLongitude(latLng.longitude);

                        // 绘制跳点
                        markerOption = new MarkerOptions();
                        markerOption.position(latLng);
                        markerOption.draggable(false);//设置Marker可拖动
                        markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory
                                .decodeResource(getResources(), R.mipmap.icon_red_point)));
                        // Marker设置为贴地显示,可以双指下拉地图查看效果
                        markerOption.setFlat(true);//设置marker平贴地图效果
                        aMap.addMarker(markerOption);

                        posTraceLocation = traceLocation;
                    }

                    else if (posCount == 202) {

                        // 创建跳点
                        TraceLocation traceLocation = originPosList.get(posCount);
                        LatLng latLng = new LatLng(traceLocation.getLatitude()+0.0160500, traceLocation.getLongitude() - 0.0160000);
                        traceLocation.setLatitude(latLng.latitude);
                        traceLocation.setLongitude(latLng.longitude);

                        // 绘制跳点
                        markerOption = new MarkerOptions();
                        markerOption.position(latLng);
                        markerOption.draggable(false);//设置Marker可拖动
                        markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory
                                .decodeResource(getResources(), R.mipmap.icon_red_point)));
                        // Marker设置为贴地显示,可以双指下拉地图查看效果
                        markerOption.setFlat(true);//设置marker平贴地图效果
                        aMap.addMarker(markerOption);

                        posTraceLocation = traceLocation;
                    }

                    else if (posCount == 203) {

                        // 创建跳点
                        TraceLocation traceLocation = originPosList.get(posCount);
                        LatLng latLng = new LatLng(traceLocation.getLatitude()+0.0160700, traceLocation.getLongitude() - 0.0160000);
                        traceLocation.setLatitude(latLng.latitude);
                        traceLocation.setLongitude(latLng.longitude);

                        // 绘制跳点
                        markerOption = new MarkerOptions();
                        markerOption.position(latLng);
                        markerOption.draggable(false);//设置Marker可拖动
                        markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory
                                .decodeResource(getResources(), R.mipmap.icon_red_point)));
                        // Marker设置为贴地显示,可以双指下拉地图查看效果
                        markerOption.setFlat(true);//设置marker平贴地图效果
                        aMap.addMarker(markerOption);

                        posTraceLocation = traceLocation;
                    }
                    else if (posCount == 204) {

                        // 创建跳点
                        TraceLocation traceLocation = originPosList.get(posCount);
                        LatLng latLng = new LatLng(traceLocation.getLatitude()+0.0160900, traceLocation.getLongitude() - 0.0160000);
                        traceLocation.setLatitude(latLng.latitude);
                        traceLocation.setLongitude(latLng.longitude);

                        // 绘制跳点
                        markerOption = new MarkerOptions();
                        markerOption.position(latLng);
                        markerOption.draggable(false);//设置Marker可拖动
                        markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory
                                .decodeResource(getResources(), R.mipmap.icon_red_point)));
                        // Marker设置为贴地显示,可以双指下拉地图查看效果
                        markerOption.setFlat(true);//设置marker平贴地图效果
                        aMap.addMarker(markerOption);

                        posTraceLocation = traceLocation;
                    }
                    else {
                        // 绘制点得到正常点
                        posTraceLocation = originPosList.get(posCount);

                    }

                    Boolean isSHow = filterPos(posTraceLocation);

                    if (isSHow) {
//                        LatLng startLocation_gps = new LatLng(posTraceLocation.getLatitude(), posTraceLocation.getLongitude());
//                        markerOption.position(startLocation_gps);
//                        markerOption.draggable(false);//设置Marker可拖动
//                        markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.icon_point)));
//                        // Marker设置为贴地显示,可以双指下拉地图查看效果
//                        markerOption.setFlat(true);//设置marker平贴地图效果
//                        aMap.addMarker(markerOption);

                        for (int i = beginPos; i < mListPoint.size(); i++) {
                            TraceLocation traceLocation = mListPoint.get(i);
                            LatLng startLocation_gps = new LatLng(traceLocation.getLatitude(), traceLocation.getLongitude());
                            MarkerOptions markerOption = new MarkerOptions();
                            markerOption.position(startLocation_gps);
                            markerOption.draggable(false);//设置Marker可拖动
                            markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory
                                    .decodeResource(getResources(), R.mipmap.icon_point)));
                            // Marker设置为贴地显示,可以双指下拉地图查看效果
                            markerOption.setFlat(true);//设置marker平贴地图效果
                            aMap.addMarker(markerOption);
                        }

                        beginPos = mListPoint.size();
                    }

                    posCount++;

                    if (posCount == 320) {
                        timer.cancel();
                    }

                }
            });
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView();

        //获取地图控件引用
        mMapView = (MapView) findViewById(R.id.map);
        //activity执行onCreate时执行mMapView.onCreate(savedInstanceState),创建地图
        mMapView.onCreate(savedInstanceState);

        if (aMap == null) {
            aMap = mMapView.getMap();
        }
    }

    @Override
    public int setContentView() {
        return R.layout.activity_show_location;
    }

    @Override
    public void initTitle() {

    }

    @Override
    public void initView() {
        mDataBinding = getDataBinding();

        BitmapDescriptor mPoint = BitmapDescriptorFactory.fromResource(R.mipmap.icon_point);
        // 设置司机定位点
        MyLocationStyle myLocationStyle;
        myLocationStyle = new MyLocationStyle();//初始化定位蓝点样式类
        myLocationStyle.myLocationIcon(mPoint);
        myLocationStyle.myLocationType(LOCATION_TYPE_LOCATE);//连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(11次定位)如果不设置myLocationType,默认也会执行此种模式。
        myLocationStyle.interval(2000); //设置连续定位模式下的定位间隔,只在连续定位模式下生效,单次定位模式下不会生效。单位为毫秒。
        aMap.setMyLocationStyle(myLocationStyle);//设置定位蓝点的Style
        aMap.getUiSettings().setMyLocationButtonEnabled(true); // 设置默认定位按钮是否显示,非必需设置。
        aMap.setMyLocationEnabled(true);// 设置为true表示启动显示定位蓝点,false表示隐藏定位蓝点并不进行定位,默认是false

        lbsTraceClient = LBSTraceClient.getInstance(APP.getInstance());
    }

    @Override
    public void initData() {
        // from local json string
        final String jsonString = ShareData.getShareStringData(ShareData.BACK_UP_POINTS);
        Type type = new TypeToken<ArrayList<TraceLocation>>() {
        }.getType();

        try {
            originPosList = new Gson().fromJson(jsonString, type);
        } catch (JsonSyntaxException e) {
            e.printStackTrace();
        }

        if (originPosList == null) {
            originPosList = new ArrayList<>();
        }
    }

    @Override
    public void processing() {

        timer.schedule(task, 20, 100);

//
//        for (int i = 0; i < originPosList.size(); i++) {
//
//            TraceLocation traceLocation = originPosList.get(i);
//            LatLng startLocation_gps = new LatLng(traceLocation.getLatitude(), traceLocation.getLongitude());
//            MarkerOptions markerOption = new MarkerOptions();
//            markerOption.position(startLocation_gps);
//            markerOption.draggable(false);//设置Marker可拖动
//            markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory
//                    .decodeResource(getResources(), R.mipmap.icon_point)));
//            // Marker设置为贴地显示,可以双指下拉地图查看效果
//            markerOption.setFlat(true);//设置marker平贴地图效果
//            aMap.addMarker(markerOption);
//        }

//        int distance = 0;
//
//        int size = mListPoint.size();
//        for (int pos=0; pos < size - 1; pos++) {
//            distance += AMapUtils.calculateLineDistance(
//                    new LatLng(mListPoint.get(pos).getLatitude(), mListPoint.get(pos).getLongitude()),
//                    new LatLng(mListPoint.get(pos+1).getLatitude(), mListPoint.get(pos+1).getLongitude())
//            );
//        }

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //activity执行onDestroy时执行mMapView.onDestroy(),销毁地图
        mMapView.onDestroy();
        timer.cancel();
    }

    @Override
    protected void onResume() {
        super.onResume();
        //activity执行onResume时执行mMapView.onResume (),重新绘制加载地图
        if (mMapView != null) {
            mMapView.onResume();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        //activity执行onPause时执行mMapView.onPause (),暂停地图的绘制
        mMapView.onPause();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        //activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState),保存地图当前的状态
        mMapView.onSaveInstanceState(outState);
    }


    @Override
    public void onRequestFailed(int i, String s) {

    }

    @Override
    public void onTraceProcessing(int i, int i1, List<LatLng> list) {

    }

    @Override
    public void onFinished(int i, List<LatLng> list, int i1, int i2) {
        for (int k = 0; k < list.size(); k++) {

            LatLng latLng = list.get(i);

            MarkerOptions markerOption = new MarkerOptions();
            markerOption.position(latLng);
            markerOption.draggable(false);//设置Marker可拖动
            markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory
                    .decodeResource(getResources(), R.mipmap.icon_red_point)));
            // Marker设置为贴地显示,可以双指下拉地图查看效果
            markerOption.setFlat(true);//设置marker平贴地图效果
            aMap.addMarker(markerOption);
        }
    }

    /**
     * @param aMapLocation
     * @return 是否获得有效点,需要存储和计算距离
     */
    private Boolean filterPos(TraceLocation aMapLocation) {

        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
        Date date = new Date(aMapLocation.getTime());
        String time = df.format(date);//定位时间
        filterString = time + "开始虑点" + "\r\n";

        try {
            // 获取的第一个定位点不进行过滤
            if (isFirst) {
                isFirst = false;
                weight1.setLatitude(aMapLocation.getLatitude());
                weight1.setLongitude(aMapLocation.getLongitude());
                weight1.setTime(aMapLocation.getTime());

                /****************存储数据到文件中,后面好分析******************/

                filterString += "第一次定位" + "\r\n";

                /**********************************/

                // 将得到的第一个点存储入w1的缓存集合
                final TraceLocation traceLocation = new TraceLocation();
                traceLocation.setLatitude(aMapLocation.getLatitude());
                traceLocation.setLongitude(aMapLocation.getLongitude());
                traceLocation.setTime(aMapLocation.getTime());
                w1TempList.add(traceLocation);
                w1Count++;

                return true;

            } else {
                filterString += "非第一次定位" + "\r\n";
//                // 过滤静止时的偏点,在静止时速度小于1米就算做静止状态
//                if (aMapLocation.getSpeed() < 1) {
//                    return false;
//                }

                /****************存储数据到文件中,后面好分析******************/
                SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
                Date date1 = new Date(aMapLocation.getTime());
                String time1 = df1.format(date1); // 定位时间
                String testString = time1 + ":" + aMapLocation.getTime() + "," + aMapLocation.getLatitude() + "," + aMapLocation.getLongitude() + "," + aMapLocation.getSpeed() + "\r\n";
                FileWriteUtil.getInstance().save("tutu_driver_true.txt", testString);

                if (weight2 == null) {
                    filterString += "weight2 == null" + "\r\n";

                    // 计算w1与当前定位点p1的时间差并得到最大偏移距离D
                    long offsetTimeMils = aMapLocation.getTime() - weight1.getTime();
                    long offsetTimes = (offsetTimeMils / 1000);
                    long MaxDistance = offsetTimes * CAR_MAX_SPEED;
                    float distance = AMapUtils.calculateLineDistance(
                            new LatLng(weight1.getLatitude(), weight1.getLongitude()),
                            new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude()));

                    filterString += "distance = " + distance + ",MaxDistance = " + MaxDistance + "\r\n";

                    if (distance > MaxDistance) {
                        filterString += "distance > MaxDistance" + "\r\n";
                        // 将设置w2位新的点,并存储入w2临时缓存
                        weight2 = new TraceLocation();
                        weight2.setLatitude(aMapLocation.getLatitude());
                        weight2.setLongitude(aMapLocation.getLongitude());
                        weight2.setTime(aMapLocation.getTime());

                        w2TempList.add(weight2);

                        return false;

                    } else {
                        filterString += "distance < MaxDistance" + "\r\n";
                        // p1加入到做坐标集合w1TempList
                        TraceLocation traceLocation = new TraceLocation();
                        traceLocation.setLatitude(aMapLocation.getLatitude());
                        traceLocation.setLongitude(aMapLocation.getLongitude());
                        traceLocation.setTime(aMapLocation.getTime());
                        w1TempList.add(traceLocation);
                        w1Count++;

                        // 更新w1权值点
                        weight1.setLatitude(weight1.getLatitude() * 0.2 + aMapLocation.getLatitude() * 0.8);
                        weight1.setLongitude(weight1.getLongitude() * 0.2 + aMapLocation.getLongitude() * 0.8);
                        weight1.setTime(aMapLocation.getTime());
                        weight1.setSpeed(aMapLocation.getSpeed());

                        if (w1TempList.size() > 3) {
                            filterString += "d1TempList.size() > 3" + "\r\n";
                            // w1TempList中的数据放入finalList,并将w1TempList清空
                            mListPoint.addAll(w1TempList);
                            w1TempList.clear();
                            return true;
                        } else {
                            filterString += "d1TempList.size() < 3" + "\r\n";
                            return false;
                        }
                    }

                } else {

                    filterString += "weight2 != null" + "\r\n";
                    // 计算w2与当前定位点p1的时间差并得到最大偏移距离D
                    long offsetTimeMils = aMapLocation.getTime() - weight2.getTime();
                    long offsetTimes = (offsetTimeMils / 1000);
                    long MaxDistance = offsetTimes * 16;
                    float distance = AMapUtils.calculateLineDistance(
                            new LatLng(weight2.getLatitude(), weight2.getLongitude()),
                            new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude()));

                    filterString += "distance = " + distance + ",MaxDistance = " + MaxDistance + "\r\n";

                    if (distance > MaxDistance) {
                        filterString += "distance > MaxDistance" + "\r\n";
                        w2TempList.clear();
                        // 将设置w2位新的点,并存储入w2临时缓存
                        weight2 = new TraceLocation();
                        weight2.setLatitude(aMapLocation.getLatitude());
                        weight2.setLongitude(aMapLocation.getLongitude());
                        weight2.setTime(aMapLocation.getTime());

                        w2TempList.add(weight2);

                        return false;
                    } else {
                        filterString += "distance < MaxDistance" + "\r\n";

                        // p1加入到做坐标集合w2TempList
                        TraceLocation traceLocation = new TraceLocation();
                        traceLocation.setLatitude(aMapLocation.getLatitude());
                        traceLocation.setLongitude(aMapLocation.getLongitude());
                        traceLocation.setTime(aMapLocation.getTime());
                        w2TempList.add(traceLocation);

                        // 更新w2权值点
                        weight2.setLatitude(weight2.getLatitude() * 0.2 + aMapLocation.getLatitude() * 0.8);
                        weight2.setLongitude(weight2.getLongitude() * 0.2 + aMapLocation.getLongitude() * 0.8);
                        weight2.setTime(aMapLocation.getTime());
                        weight2.setSpeed(aMapLocation.getSpeed());

                        if (w2TempList.size() > 4) {
                            filterString += "w2TempList.size() > 4" + "\r\n";
                            // 判断w1所代表的定位点数是否>4,小于说明w1之前的点为从一开始就有偏移的点
                            if (w1Count > 4) {
                                filterString += "w1Count > 4" + "\r\n";
                                mListPoint.addAll(w1TempList);
                            } else {
                                filterString += "w1Count < 4" + "\r\n";
                                w1TempList.clear();
                            }

                            // w2TempList集合中数据放入finalList
                            mListPoint.addAll(w2TempList);

                            // 1、清空w2TempList集合 2、更新w1的权值点为w2的值 3、将w2置为null
                            w2TempList.clear();
                            weight1 = weight2;
                            weight2 = null;
                            return true;

                        } else {
                            filterString += "w2TempList.size() < 4" + "\r\n";
                            return false;
                        }
                    }
                }
            }
        } finally {
//            FileWriteUtil.getInstance().save("tutu_driver_filter.txt", filterString);
//            Log.d("hhh","finnaly");
            Log.d("hhh",filterString);
        }


    }
}

 

 

  • 15
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
以下是一个使用高德地图纠偏API的调用实例: 假设我们有一组GPS坐标数据,经度为120.123456,纬度为31.654321。这些坐标数据是从一台设备上收集到的,但是由于设备误差等原因,这些坐标数据可能存在偏差。我们希望通过高德地图纠偏API将这些坐标数据进行纠偏,得到更准确的位置信息。 首先,我们需要准备以下参数: 1. 高德地图API的请求地址:https://restapi.amap.com/v3/assistant/coordinate/convert 2. API的请求参数: 参数名 | 参数含义 | 示例值 ----- | ------- | ----- key | 高德地图API的密钥 | abcdefg123456789 locations | 待纠偏的坐标数据 | 120.123456,31.654321 coordsys | 待纠偏的坐标系,可选值为gps、mapbar、baidu、autonavi,默认为gps | gps 然后,我们可以使用Python的requests库来发起API请求,代码如下: ```python import requests key = 'abcdefg123456789' locations = '120.123456,31.654321' coordsys = 'gps' url = 'https://restapi.amap.com/v3/assistant/coordinate/convert?key={}&locations={}&coordsys={}'.format(key, locations, coordsys) response = requests.get(url) if response.status_code == 200: data = response.json() if data['status'] == '1': result = data['locations'] print('纠偏后的坐标为:{}'.format(result)) else: print('API请求失败,错误信息为:{}'.format(data['info'])) else: print('API请求失败,状态码为:{}'.format(response.status_code)) ``` 以上代码将向高德地图API发送一个GET请求,并将API返回的JSON数据解析出纠偏后的坐标。最后,程序会输出纠偏后的坐标,例如: ``` 纠偏后的坐标为:120.1290235512,31.6507305337 ``` 这个坐标比原始坐标更准确,可以用于进一步的位置分析和应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值