Android GPS位置波动
我在谷歌地图上画的心脏是一条多段线,取决于半径(1-100米)。一旦心脏被绘制出来,用户需要在心脏边界上行走,并且需要从头到尾完成(从底部开始,然后向左,然后向右,然后再次从底部行走) 我能够吸引人心,我得到了360分。这是我的代码,它将绘制心脏和图像Android GPS位置波动,android,gps,google-maps-android-api-2,google-location-services,Android,Gps,Google Maps Android Api 2,Google Location Services,我在谷歌地图上画的心脏是一条多段线,取决于半径(1-100米)。一旦心脏被绘制出来,用户需要在心脏边界上行走,并且需要从头到尾完成(从底部开始,然后向左,然后向右,然后再次从底部行走) 我能够吸引人心,我得到了360分。这是我的代码,它将绘制心脏和图像 private void initPath() { path = new PolylineOptions(); path.color(ContextCompat.getColor(mActivity,R.color.heart_g
private void initPath() {
path = new PolylineOptions();
path.color(ContextCompat.getColor(mActivity,R.color.heart_green));
path.width(25);
// offset to bottom
double offsetY = getY(Math.toRadians(180));
for (int angle = 0; angle <= 360; angle++) {
double t = Math.toRadians(angle);
double x = getX(t);
double y = getY(t) - offsetY;
//Log.d(TAG, "angle = " + angle + "(x = " + x + ",y= " + y + ")");
//convert x,y to lat lng
LatLng latLng = getLatLng(x, y, center);
path.add(latLng);
heart360Points.add(latLng);
}
}
private double getX(double t) {
return radius * 16 * Math.sin(t) * Math.sin(t) * Math.sin(t) / HEART_RATIO;
}
private double getY(double t) {
return radius * (13 * Math.cos(t) - 5 * Math.cos(2 * t) - 2 * Math.cos(3 * t) - Math.cos(4 * t)) / HEART_RATIO;
}
private LatLng getLatLng(double dx, double dy, LatLng centerHeart) {
return new LatLng(centerHeart.latitude + Math.toDegrees(dy / EARTH_RADIUS),
centerHeart.longitude + Math.toDegrees(dx / EARTH_RADIUS) / Math.cos(Math.toRadians(centerHeart.latitude)));
}
我不明白为什么GPS位置波动太大。即使我站着,我也会得到不同的GPS位置
如何获得准确的GPS位置?介绍了GPS系统错误的基本知识,例如。将来自GPS(IMHO原始、未过滤、从/接收的GPS数据)和其他传感器(加速计、陀螺仪、磁强计等)的数据进行融合可以提高精度,但目前不可能创建具有所述功能的良好应用程序(100米左右的轨迹“复杂”图)。如果简化路径(如图所示)
轨道交叉口检查站“geofence”及其顺序-可能是您可以实现功能,但在许多情况下准确性是不可接受的。位置的波动是它的正常行为。问题是,何时/如何接受或放弃意外位置。正如用户(Patrick Artner)所评论的,您应该放弃突然的侧面移动 你可以通过两种方式放弃这些动作
只需接受小于5米和大于1米的位置(您可以根据自己的理解选择距离范围) 无法获得精确的GPS坐标是很常见的,因为这取决于许多因素,如
- 露天或室内条件
- 云层、建筑物等障碍物
- 设备/CPU电源上的GPS芯片配置
- 蜂窝网络信号强度
- 使用@andrii omelchenko建议的卡尔曼滤波算法
- 或者您可以使用该机制设置geofence,android系统将在您进入/退出geofence时为您提供回调
- A) 设置少量土工栅栏圈(下一组板条可能为3~5圈)
- B) 进入该土工围栏时,将步骤标记为完成
- C) 重复A,直到用户覆盖整个心脏
- 与上述地理围栏逻辑一起使用,以检查用户是否正在行走
是的,gps位置波动是正常的,但如果您想要更高的精度,请做一件事。我给你看我的把戏 我相信你也在做同样的事情。只是给你指路 第1步。上这个班 GoogleLocationService.java
public class GoogleLocationService {
private GoogleServicesCallbacks callbacks = new GoogleServicesCallbacks();
LocationUpdateListener locationUpdateListener;
Context activity;
protected GoogleApiClient mGoogleApiClient;
protected LocationRequest mLocationRequest;
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 2000;
public GoogleLocationService(Context activity, LocationUpdateListener locationUpdateListener) {
this.locationUpdateListener = locationUpdateListener;
this.activity = activity;
buildGoogleApiClient();
}
protected synchronized void buildGoogleApiClient() {
//Log.i(TAG, "Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(activity)
.addConnectionCallbacks(callbacks)
.addOnConnectionFailedListener(callbacks)
.addApi(LocationServices.API)
.build();
createLocationRequest();
mGoogleApiClient.connect();
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
private class GoogleServicesCallbacks implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
@Override
public void onConnected(Bundle bundle) {
startLocationUpdates();
}
@Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
if (connectionResult.getErrorCode() == ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED) {
Toast.makeText(activity, "Google play service not updated", Toast.LENGTH_LONG).show();
}
locationUpdateListener.cannotReceiveLocationUpdates();
}
@Override
public void onLocationChanged(Location location) {
if (location.hasAccuracy()) {
if (location.getAccuracy() < 30) {
locationUpdateListener.updateLocation(location);
}
}
}
}
private static boolean locationEnabled(Context context) {
boolean gps_enabled = false;
LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
try {
gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch (Exception ex) {
ex.printStackTrace();
}
return gps_enabled;
}
private boolean servicesConnected(Context context) {
return isPackageInstalled(GooglePlayServicesUtil.GOOGLE_PLAY_STORE_PACKAGE, context);
}
private boolean isPackageInstalled(String packagename, Context context) {
PackageManager pm = context.getPackageManager();
try {
pm.getPackageInfo(packagename, PackageManager.GET_ACTIVITIES);
return true;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return false;
}
}
public void startUpdates() {
/*
* Connect the client. Don't re-start any requests here; instead, wait
* for onResume()
*/
if (servicesConnected(activity)) {
if (locationEnabled(activity)) {
locationUpdateListener.canReceiveLocationUpdates();
startLocationUpdates();
} else {
locationUpdateListener.cannotReceiveLocationUpdates();
Toast.makeText(activity, "Unable to get your location.Please turn on your device Gps", Toast.LENGTH_LONG).show();
}
} else {
locationUpdateListener.cannotReceiveLocationUpdates();
Toast.makeText(activity, "Google play service not available", Toast.LENGTH_LONG).show();
}
}
//stop location updates
public void stopUpdates() {
stopLocationUpdates();
}
//start location updates
private void startLocationUpdates() {
if (checkSelfPermission(activity, ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(activity, ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, callbacks);
}
}
public void stopLocationUpdates() {
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, callbacks);
}
}
public void startGoogleApi() {
mGoogleApiClient.connect();
}
public void closeGoogleApi() {
mGoogleApiClient.disconnect();
}
}
public interface LocationUpdateListener {
/**
* Called immediately the service starts if the service can obtain location
*/
void canReceiveLocationUpdates();
/**
* Called immediately the service tries to start if it cannot obtain location - eg the user has disabled wireless and
*/
void cannotReceiveLocationUpdates();
/**
* Called whenever the location has changed (at least non-trivially)
* @param location
*/
void updateLocation(Location location);
/**
* Called when GoogleLocationServices detects that the device has moved to a new location.
* @param localityName The name of the locality (somewhere below street but above area).
*/
void updateLocationName(String localityName, Location location);
}
您可以在需要更新位置的类中直接调用下面的代码,并删除locationservice
private GoogleLocationService googleLocationService;
googleLocationService = new GoogleLocationService(context, new LocationUpdateListener() {
@Override
public void canReceiveLocationUpdates() {
}
@Override
public void cannotReceiveLocationUpdates() {
}
//update location to our servers for tracking purpose
@Override
public void updateLocation(Location location) {
if (location != null ) {
Timber.e("updated location %1$s %2$s", location.getLatitude(), location.getLongitude());
}
}
@Override
public void updateLocationName(String localityName, Location location) {
googleLocationService.stopLocationUpdates();
}
});
googleLocationService.startUpdates();
and call this onDestroy
if (googleLocationService != null) {
googleLocationService.stopLocationUpdates();
}
如果你看,我做了一件事。getAccurance()以米为单位描述偏差。因此,数字越小,准确度越高。
public void onLocationChanged(Location location) {
if (location.hasAccuracy()) {
if (location.getAccuracy() < 30) {
locationUpdateListener.updateLocation(location);
}
}
}
public void onLocation已更改(位置){
if(location.hasAccurance()){
if(location.getAccurance()<30){
位置UpdateListener.updateLocation(位置);
}
}
}
谢谢,希望这能对你有所帮助。你在manifest.xml上调用的权限是什么?也许你需要参军——我听说他们比普通人获得更好的GSP数据:)但我认为你并不是唯一一个遇到这个问题的人,甚至连口袋妖怪(我不玩)也一直在地图上摇摆不定。因此,您可能会受到设备上GPS信号的“默认”随机性的影响,这可能会受到您的位置(隧道、建筑物、树木==跟踪GPS所需的卫星)和/或天气的影响-这似乎会影响地理缓存。是的,这是真的,但“Waz3”、“Ub3r”和正确的“G00gle方向”也是真的工作起来很有魅力,动作流畅,精度在几米左右。。。我想他们对我们隐藏了一些秘密,小开发者。@statosdotcom-他们可能会将手机定位数据与gps结合起来,或者根据移动速度平均5到20秒的数据,以消除锯齿形移动。甚至可能放弃基于最近n个位置的向量的突然“侧移”,即大量填充/删除错误数据和预测“好”样本的内容。@PatrickArtner很好的分析和评论,谢谢。你是完全正确的,这不仅仅是一个使用正确工具的问题,而是将其与人类理性方面的知识结合起来,也就是说,不只是盲目地说谎技术数据,而是使用准确的数据来预测发生了什么。人+机器。。。哇。。。我们要去哪里D
public void onLocationChanged(Location location) {
if (location.hasAccuracy()) {
if (location.getAccuracy() < 30) {
locationUpdateListener.updateLocation(location);
}
}
}