我想在谷歌地图上绘制路径。
基本上我在特定的时间间隔后跟踪用户位置。当用户到达某个目的地时,我需要绘制他到达目的地的路径。
它工作正常,但问题是它显示之字形路径。见下图。
我想要的是什么:
我想绘制一条正确的路径,然后是我在跟踪过程中得到的分数。
我尝试了什么
我搜索并找到了this链接,其中我们可以通过最多8个点来获取路线。这是Google地图的非商业用户允许的最高限额。有没有其他方法来实现这一目标。因为我在地图上画了很多分。
绘制折线的代码
private void drawPath() {
if (mMap != null)
mMap.clear();
int count = 0;
LatLng prev = null;
String[] mProjection = {LocTable.COLUMN_ID, LocTable.COLUMN_LONGITUDE, LocTable.COLUMN_LATITUDE};
String mSelectionClause = LocTable.COLUMN_ID + "> ?";
String[] mSelectionArgs = {"0"};
String mSortOrder = LocTable.COLUMN_ID;
Cursor mCursor = getContentResolver().query(
LocContentProvider.CONTENT_URI, // The content URI of the words table
mProjection, // The columns to return for each row
mSelectionClause, // Selection criteria
mSelectionArgs, // Selection criteria
mSortOrder);
if(mCursor != null && mCursor.getCount()!=0) {
Log.i("cursor", "Count: " + mCursor.getCount() + "|Column count: " + mCursor.getColumnCount());
if (mCursor.moveToFirst()) {
do {
if (mMap != null) {
float lon = mCursor.getFloat(1);
float lat = mCursor.getFloat(2);
LatLng current = new LatLng(lat, lon);
markerPoints.add(current);
if (count == 0){
prev = current;
}
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(current, 19);
mMap.animateCamera(cameraUpdate);
mMap.addPolyline((new PolylineOptions())
.add(prev, current).width(6).color(Color.BLUE)
.visible(true));
prev=current;
count++;
}
} while (mCursor.moveToNext());
}
mCursor.close();
}
}
答案 0 :(得分:6)
我同意antonio的回答。问题不在于你的绘图功能。您只需绘制路径,无论您的位置是什么设备。问题是您的设备没有提供准确的位置。
让我简要介绍一下位置功能。</ p>
有三种提供商在设备中提供位置。
此提供商使用卫星确定位置。根据条件,此提供程序可能需要一段时间才能返回位置修复程序。需要权限ACCESS_FINE_LOCATION。
GPS位置提供商的附加包可以包含以下键/值对:
卫星 - 用于导出修复的卫星数量
此提供商根据手机信号塔和WiFi接入点的可用性确定位置。通过网络查找检索结果。
当其他应用程序或服务请求时,此提供程序可用于被动地接收位置更新,而无需自己实际请求位置。此提供程序将返回其他提供程序生成的位置。您可以查询getProvider()方法以确定位置更新的来源。需要权限ACCESS_FINE_LOCATION,但如果未启用GPS,则此提供程序可能仅返回粗略修复。
参考:
Android Location Providers - GPS or Network Provider?
根据我的经验,我可以说
GPS Provider
正在给你准确 位置与Network Provider
比较但需要开放环境,GPS provider
无法在建筑物内部给出准确的位置。
返回描述此提供程序的水平精度的常量。如果提供者返回更精细的粒度或确切位置,则返回ACCURACY_FINE
,否则如果该位置仅为近似值,则返回ACCURACY_COARSE
。
当从GPS提供商更改位置时,此方法将返回精确值,否则将返回近似值或0值。
<强>解决方案:强>
仅使用GPS提供程序
建议使用Google客户端 Sample Example.
答案 1 :(得分:4)
问题不在于绘图功能,而在于您使用接收位置获取路径点的方法。
您需要考虑两个因素:
Location.getAccuracy()
方法(documentation)获得准确性。精度以米为单位,因此越低越好。结合两个注意事项的示例:
private static final float MINIMUM_ACCURACY = 10; // If the accuracy of the measurement is worse than 10 meters, we will not take the location into account
private static final float MINIMUM_DISTANCE_BETWEEN_POINTS = 20; // If the user hasn't moved at least 20 meters, we will not take the location into account
private Location lastLocationloc;
// ...
public void onLocationChanged(Location mylocation) {
if (mylocation.getAccuracy() < MINIMUM_ACCURACY) {
if (lastLocationloc == null || lastLocationloc.distanceTo(mylocation) > MINIMUM_DISTANCE_BETWEEN_POINTS) {
// Add the new location to your polyline
lastLocationloc = mylocation;
}
}
}
答案 2 :(得分:1)
你有没有看过新的Roads Api?它将计算精度并返回最合理的值来绘制线。它还提供当前道路的速度限制。
答案 3 :(得分:0)
添加到@antonio回答。您可以按如下方式指定优先级和位移。这将确保您可以获得最大可能的准确度
private int mInterval =5;
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10;
private static final float MIN_ACCURACY = 10;
private Location lastKnownLocation;
@Override
public void onConnected(Bundle bundle) {
locationRequest = LocationRequest.create();
locationRequest.setInterval(mInterval * 1000); // milliseconds
locationRequest.setFastestInterval(mInterval * 1000);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setSmallestDisplacement(MIN_DISTANCE_CHANGE_FOR_UPDATES);//distance change
int permissionCheck = ContextCompat.checkSelfPermission(appContext, Manifest.permission.ACCESS_COARSE_LOCATION);
if (permissionCheck!= PackageManager.PERMISSION_DENIED)
{ LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient,
locationRequest, this);
}
}
现在在onLocationChanged方法中按照建议做。
@Override
public void onLocationChanged(Location location) {
if (location.getAccuracy() < MIN_ACCURACY ) {
if (lastKnownLocation == null || lastKnownLocation.distanceTo(location) > MIN_DISTANCE_CHANGE_FOR_UPDATES) {
lastKnownLocation = location;
}
}
}
注意:
从NetworkProvider检索位置时更快,甚至更快 如果设备是静态的,则在特定间隔内接收的位置 变化。上述逻辑将使我们有机会避免 不相关的值并跟踪/处理有效值。