如何通过 GPS_PROVIDER 获得更高的准确性

Posted

技术标签:

【中文标题】如何通过 GPS_PROVIDER 获得更高的准确性【英文标题】:How to get more accuracy by GPS_PROVIDER 【发布时间】:2014-08-25 12:48:03 【问题描述】:

我有一个挑战任务是要获得非常高的准确度。所以我正在使用 GPS_PROVIDER。但我的代码得到不正确的准确性。有时它会显示距离我当前位置 10 到 50 米。有时它会向我显示 距我当前位置 5 到 15 米的距离。我已经测试了 XOLO 和 Sony 两种设备。我已经解决了这些问题,但无法解决。 这是我的代码:-

@Override
protected void onResume() 
    super.onResume();

    if(mMap!= null)
        mMaprivate LatLng geo;
map.clear();

    locationManager = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);             
    mFragment = (SupportMapFragment) this.getSupportFragmentManager().findFragmentById(R.id.map);
    mMap = mFragment.getMap(); 
    
   setListener();
 

private void setListener()     
    System.out.println("setListener()  locationListener = "+locationListener);
    if(locationListener != null)
        clearListener();
    

    Toast toast = Toast.makeText(this, this.getResources().getString(R.string.maps_loading), Toast.LENGTH_LONG);
    toast.show();   
    private LatLng geo;

    locationListener = new CustomLocationListener();

    Criteria criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_FINE);
    //criteria.setAccuracy(Criteria.ACCURACY_HIGH);
    criteria.setPowerRequirement(Criteria.NO_REQUIREMENT);
    String bestProvider = locationManager.getBestProvider(criteria, true); 
    Toast.makeText(this, "bestProvider= "+bestProvider, Toast.LENGTH_SHORT).show();
//  locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
   locationManager.requestLocationUpdates(bestProvider, 0, 0, locationListener);

    handler=new Handler();
    timeoutTask = new TimeoutTask(locationListener);
    handler.postDelayed(timeoutTask, 50*1000);


private void clearListener()
    if(locationListener != null)
        locationManager.removeUpdates(locationListener);
        locationListener = null;
    


private void gotLocation(Location location)
    loc = location;
    System.out.println("getLocation = "+location.getLatitude());
 //   Toast.makeText(getBaseContext(), "new Lat = "+location.getLatitude(), Toast.LENGTH_LONG).show();


public class CustomLocationListener implements LocationListener 
    private boolean isCompleted = false;

    public CustomLocationListener() 

    @Override
    public void onLocationChanged(Location location) 
        isCompleted=true;

        System.out.println("onLocationChanged 1");

          // Called when a new location is found by the GPS location provider.
          if(isBetterLocation(location, loc))
            //  Toast.makeText(getBaseContext(), "yes", Toast.LENGTH_LONG).show();
              System.out.println("onLocationChanged 2");
              gotLocation(location);
          
          System.out.println("onLocationChanged 3");
          clearListener();
          setUserPoint();
    

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras)  

    @Override
    public void onProviderEnabled(String provider)  

    @Override
    public void onProviderDisabled(String provider)  

    public boolean isCompleted() 
        return isCompleted;
    private LatLng geo;

   
private LatLng geo;

 public class TimeoutTask implements Runnable 

    private CustomLocationListener listener;

    public TimeoutTask(CustomLocationListener listener) 
        this.listener=listener;
    

    @Override
    public void run() 
        // TODO Auto-generated method stub
        if (listener == null || listener.isCompleted()) 
            Log.e("provider", "completed");
       
        else 
            Toast.makeText(ScorecardMapViewActivity.this, "We were unable to find your position, please try again", Toast.LENGTH_LONG).show();
            Log.e("provider", "timeout");
            clearListener();
            setUserPoint();
            if(goToScorecardStep3WithLocation) finish(); 
        
    




protected boolean isBetterLocation(Location location, Location currentBestLocation) 
    if (currentBestLocation == null) 
        // A new location is always better than no location
        return true;
    

    // Check whether the new location fix is newer or older
    long timeDelta = location.getTime() - currentBestLocation.getTime();
    boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
    boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
    boolean isNewer = timeDelta > 0;

    // If it's been more than two minutes since the current location, use the new location
    // because the user has likely moved
    if (isSignificantlyNewer) 
        return true;
    // If the new location is more than two minutes older, it must be worse
     else if (isSignificantlyOlder) 
        return false;
    

    // Check whether the new location fix is more or less accurate
    int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
    boolean isLessAccurate = accuracyDelta > 0;
    boolean isMoreAccurate = accuracyDelta < 0;
    boolean isSignificantlyLessAccurate = accuracyDelta > 200;

    // Check if the old and new location are from the same provider
    boolean isFromSameProvider = isSameProvider(location.getProvider(),
            currentBestLocation.getProvider());

    // Determine location quality using a combination of timeliness and accuracy
    if (isMoreAccurate) 
        return true;
     else if (isNewer && !isLessAccurate) 
        return true;
     else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) 
        return true;
    
    return false;


private LatLng geo;

private void setUserPoint() 
    if(!goToScorecardStep3WithLocation) 
    if(loc != null) 

         if(handler != null)  System.out.println("removed timeout task from handler");
            handler.removeCallbacks(timeoutTask); 

        geo = HelperUtil.getLatLng(loc);
        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(geo, 18));
        mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);

        System.out.println("loc.getLatitude() = "+loc.getLatitude());
        System.out.println("loc.getLongitude() = "+loc.getLongitude());

        // your current position show.
         mMap.addMarker(new MarkerOptions().title("Player").position(geo)
        .icon(BitmapDescriptorFactory.fromResource(R.drawable.map_point)));



请任何一位专家帮助我。您的帮助将非常有帮助。 谢谢!

更新:-

我注意到我是否在同一个地方。有时我会得到长小数点,有时会得到小数点。由于小数点,计算距离是否有任何影响?我正在计算院子里的距离。

当前位置 = 纬度 28.65361000000004 长 = 77.4122733333333

以前的当前位置点(这是同一个地方,但纬度/经度不同)

纬度 = 28.653685000000003 长 = 77.4123083333334

我有 8 码的距离。我认为一些问题可能是由于长或小的数字点。 有没有办法让我们只得到长小数点?

【问题讨论】:

你在哪里测试你的应用程序??根据 GPS 并非无处不在(即建筑物内)的事实。因此,他们使用其他供应商(WiFi、网络等)以及侧面传感器来提供可能的最佳位置。 精度通常一直在变化(取决于您所在的位置)。您对此无能为力。有些设备有更好的 GPS(比如那些使用 GLONASS 卫星的设备)。 @Sree 是的,我正在户外或露天测试 @Hardy 说的,这完全取决于,我们不知道你是怎么得到的,最好尝试不同的地方和设备,准确度总是会改变 @Hardy 有没有一种方法可以修复它?或任何逻辑 【参考方案1】:

消费类 GPS 接收器在 95% 的情况下具有 2.5-6m 的精度,对于移动设备,您无法提高它。

如果您静止不动(通过用户交互告知静止开始和静止结束),您可以计算平均位置。 尤其是在静止不动时,GPS 芯片的精度会降低一些,因为多普勒频移只能在移动时使用。

要计算设备的准确度,您应该采取一些措施,计算平均位置,并计算每次测量到该平均位置的距离。 那么这应该给出3-6m之间的值。

您写道,您希望在静止不动时两个位置之间的距离为 0 米。 但这不适用于 GPS。由于对流层的波动条件,信号延迟略有变化,导致静止不动时的跳跃位置。

如果你启用了 ios 默认使用的静止过滤器,你只会得到 0m。 android 中也应该有可能启用这样的过滤器(例如,通过将距离阈值设置为高于 0 的值)。

【讨论】:

【参考方案2】:

OnLocation 方法中检查定位精度,如果不合适,下次调用OnLocation 通常会更准确。更高的准确性需要更多的工作。您已经看到谷歌地图在该位置周围显示了一个圆圈,并且可能看到它的大小减小了。圆的半径取决于位置精度,它是 Location 的一个属性。

下面的方法效果很好。我在开车、骑自行车、遛狗和哈雷时对它进行了广泛的测试。它会过滤掉进入 Mcd's 并让位置出现在 Mcd 的 wifi 提供商所在的德克萨斯州以及相距 100m 位置的那些讨厌的位置。

@Override
public void onLocationChanged(Location location) 


    if (!location.hasAccuracy()) 
            return;
        
        if (location.getAccuracy() > myDesiredAccuracy) 
            return;
        

//blah what your app does...

    isCompleted=true;

    System.out.println("onLocationChanged 1");

      // Called when a new location is found by the GPS location provider.
      if(isBetterLocation(location, loc))
        //  Toast.makeText(getBaseContext(), "yes", Toast.LENGTH_LONG).show();
          System.out.println("onLocationChanged 2");
          gotLocation(location);
      
      System.out.println("onLocationChanged 3");
      clearListener();
      setUserPoint();

注意:有时您会遇到无法获得良好 GPS 接收的死角。这些是由于建筑物内、电源线、视线、高速公路中断、建筑物中未映射的 wifi、其他发射无线电信号的设备干扰 GPS 卫星接收而引起的。基本上任何会干扰无线电接收的东西都会干扰 GPS。

【讨论】:

嗨@danny117 你会设置什么精度设置来跟踪跑步者?我正在构建一个正在运行的应用程序并想知道。 我会在 google 位置提供商处进行 5 秒 40 米。类似于每 5 秒向我发送一次位置信息,但仅限于距离超过 40 米时。

以上是关于如何通过 GPS_PROVIDER 获得更高的准确性的主要内容,如果未能解决你的问题,请参考以下文章

使用类似于 Lenet5 的架构对“101 个对象类别”数据进行分类,获得比预期更高的准确度

与 LSTM 中的 sigmoid + binary_crossentropy 相比,使用 softmax + categorical_crossentropy 获得更高的准确度

训练神经网络时如何在准确性/减少损失方面给予特定输出更高的优先级

cassandra lucene - 如何获得更高的分数

如何优化我的实体框架查询以获得更好的性能和更高的可读性

在linux内核中获得比jiffies精度更高的时间值转