简单处理GPS漂移计算方法

class test{
   
   private LocationPojo preLocation;

    private List<LocationPojo> nowLocation;

    private Long preTime;
   
   public boolean test(List<LocationPojo> now,LocationPojo pre) {
      this.nowLocation = now;
      this.preLocation = pre;
      

        double distance = 0;//两点坐标点距离
        int tmp = 40;//精准度上行初始阀值(固定)
      
        int AccuracyThresholdUp = tmp;//精准度上行阀值
        int AccuracyThresholdDown = 30;//精准度下行阀值

        int stopCount = 0; //静止状态坐标计数
        int rectCountDown = 0; //坐标在30M围栏内计数
        int rectCountUp = 0;  //坐标在100M围栏外计数
      
        int notCheckUpCount = 0; //超出大围栏计数,不检查精准度

      /*
       *
       * 如果没有上一次的GPS数据,那么直接返回这次的GPS数据。
      **/
        if (this.preLocation() == null){
            this.preLocation(this.nowLocation.get(0));
            this.preTime = this.preLocation().getAddTime();//上一次记录的时间
            return true;
        }

        LocationPojo b = null;

        //循环计数(我这边是每次定位间隔是1秒,每次定位数据达到10条后进入计算,所以有这个循环)
      //就是用10条现在的GPS数据与上一次的GPS数据,进行数据计算。
        for (LocationPojo pojo:this.nowLocation){
            if (b == null){
                b = pojo;
            }

            //判断不是GPS数据,如果不是,改变阀值的上下值
            if (pojo.getProvider().equals(GPS.GPS)) {
                AccuracyThresholdUp = (int)(tmp * 1.5);//网络定位普遍在40以上,所以需要改变精准度的阀值。
            }else{
                AccuracyThresholdUp = tmp;//由于是循环的,所以每次都需要重新赋值。
            }

            //没有速度,或者有速度但是精准度很高,我会把这类的数据归于静止状态(GPS漂移数据)
            if (pojo.getSpeed() <= 0 || (pojo.getSpeed() > 0 && pojo.getAccuracy() > AccuracyThresholdDown)){
                stopCount++;
            }

            //测算距离(测算距离的方法有很多,我现在把它封装成工具类了)
            distance = CommUtils.getLocationDistance(pojo.getLatitude(),pojo.getLongitude(),preLocation.getLatitude(),preLocation.getLongitude());

            //优化速度精准度
            if(pojo.getSpeed() > 0 && distance > 0){
                //距离 / 时间 * 3.6 = 速度(KM)
//                float speed = CommUtils.fromatNumber(distance / ((pojo.getAddTime() - this.preTime) / 1000) * 3.6,null);
//                pojo.setSpeed(speed);
                pojo.setSpeed(CommUtils.formatNumber(pojo.getSpeed().doubleValue(),"#0.00").floatValue());
            }

            //latlnt电子围栏 30 - 100m
            //超出围栏(条件是:lat或者lnt与上一次坐标匹配大于[100m]并且精确度在30m以内,条件成立)
            if (distance > 100){
                notCheckUpCount++;

            //高精准度(GPS数据应该是可靠的)
                if(pojo.getAccuracy() < AccuracyThresholdUp){
                    rectCountUp++;

                    //如果上一次GPS精准度大于这一次,那么次数GPS数据是有效的。
                    if(pojo.getAccuracy() <= preLocation.getAccuracy()){
                        b = pojo;
                    }
                }
            }else if (distance > 30 && pojo.getAccuracy() < AccuracyThresholdUp){
                //如果在电子围栏内,并且精确度在30m以内,条件成立
                rectCountDown++;
                if(pojo.getAccuracy() <= preLocation.getAccuracy()){
                    b = pojo;
                }
            }
            
        }

        //a:在30米的围栏中必须有速度值,而且超出小围栏的计数>=5个,条件成立则正在移动(30M直径的正方形)
        //a1:在100米的围栏中有8个条数据均超出,不管有没有速度,条件均成立(也许他是坐飞机,也许他瞬移)
        double a = getNowLocation().size() * 0.5;
        double a1 = getNowLocation().size() * 0.8;
        if ((stopCount <= 5 && rectCountDown >= a) || rectCountUp >= a1 || (notCheckUpCount == getNowLocation().size() && rectCountUp >= a) || (stopCount >= a && rectCountUp >= a)){
            this.setPreLocation(b);
            this.setPreTime(b.getAddTime());
            return true;
        }
        return false;

    }
}

Leave a Comment