众所周知,GPS系统远非完美无缺,当GPS丢失信号并再次开始计算时,当您使用gps使用应用程序时。如果您尝试正确计算距离,它将开始计算,例如,如果您距离目的地30米,它将计算例如130米。哪个混淆了我如何计算距离。所以我发现了一些建议,我应该使用速度来过滤GPS协调。
我想计算没有location.getSpeed()
的速度我想通过比较从最后已知坐标到某个给定点的坐标的距离来计算速度,我得到设备移动的速度。如果速度例如大于15米/小时,则坐标无效,并且不会重新计算距离。
答案 0 :(得分:1)
就像V =(距离)/(经过时间)一样简单。 因此,假设您在时间X读取了您的location1。 在X之后的某个时刻让我们在Y时刻再次读到您的位置。 比你没有
float distance = location1.distanceTo(location2);
以米为单位浮动(请参阅此http://developer.android.com/reference/android/location/Location.html#distanceTo(android.location.Location)
如果计算X - Y为
,则以速度为单位,以米/秒为单位float X = System.currentTimeMillis(); //When you get the first location
float Y = System.currentTimeMillis(); //When you get the second location
//...
//Than when calculating
float timeElapsed= (Y - X)/1000; //In seconds
比以秒为单位的速度
float V = distance/timeElapsed;
如果你想计算平均速度,你需要将速度存储在列表中,然后计算每两点之间计算的所有速度的平均值。因此,如果你有位置l1,l2,l3,l4 ...... ln,V1将是l1和l2之间的速度,V2将在l2和l3之间,并且Vn-1将在ln-1和ln之间。您将所有Vn存储在列表中(例如),而不是将平均值计算为
Vavg =(V1 + V2 + V3 ... + Vn)/ n
<强>更新强> 在您的活动中
Location previousLocation = null;
float previousTime = 0;
float velocity = 0;
比:
public void onLocationChanged(Location loc) {
boolean hasPrevious = true;
if (previousLocation == null || previousTime == 0) {
hasPrevious = false;
}
float currentTime = System.currentTimeMillis();
if (hasPrevious) {
float timeElapsed = (currentTime - previousTime)/1000;
velocity = loc.distanceTo(previousLocation)/timeElapsed;
}
storeToPrevious(loc, currentTime);
}
以不同的功能
private void storeToPrevious(Location l, float time) {
previousLocation = new Location(l);
previousTime = time;
}
答案 1 :(得分:1)
这可能会做你想要的。它写在Kotlin。它应用加权移动平均线。最近的位置重量较重。它可以&#34;平滑&#34;超出速度,代价是增加更多滞后。这是为了解决某些我无法使用getSpeed()的情况。但通常情况下,如果您使用&#34; Fused&#34;在Android上的位置,在典型的现代ACTIVE手机上速度非常稳定和准确。
var recentGPSLocationSegments = listOf<Pair<android.location.Location, android.location.Location>>()
fun applyWeightedMovingAverageSpeed(location: android.location.Location, previous: android.location.Location): Double
{
recentGPSLocationSegments += Pair(location, previous)
val cachedLocationsNs = location.elapsedRealtimeNanos - 4500000000 // 4.5 seconds, This will typically get 4 entries (1 second apart)
val targetZeroWeightNs = location.elapsedRealtimeNanos - 5000000000 // 5.0 seconds, Weights will be approx 5000000000, 4000000000, 3000000000, 1000000000
// Toss old locations
recentGPSLocationSegments = recentGPSLocationSegments.filter { it -> it.first.elapsedRealtimeNanos > cachedLocationsNs }
// Total up all the weights. Weight is based on age, younger has higher weight
val weights = recentGPSLocationSegments.map { it.first.elapsedRealtimeNanos - targetZeroWeightNs }.sum()
// Apply the weights and get average speed in meters/second
return recentGPSLocationSegments.map { speedFromGPS(it.first, it.second) * (it.first.elapsedRealtimeNanos - targetZeroWeightNs) }.sum() / weights
}
fun speedFromGPS(location: android.location.Location, previous: android.location.Location): Double
{
val dist = location.distanceTo(previous)
val time = (location.elapsedRealtimeNanos - previous.elapsedRealtimeNanos) / 1000000000.0
return dist / time
}
val locationManagerExample: LocationListener = object : LocationListener
{
var lastLocation: android.location.Location? = null
var lastPreviousLocation: android.location.Location? = null
override fun onLocationChanged(location: android.location.Location?)
{
if (location != null)
{
if (lastPreviousLocation != null)
{
currentSpeed = applyWeightedMovingAverageSpeed(location, lastPreviousLocation!!)
lastPreviousLocation = lastLocation
}
lastLocation = location
if (currentSpeed < 0.0)
{
currentSpeed = 0.0
}
}
}
override fun onStatusChanged(provider: String, status: Int, extras: Bundle)
{
}
override fun onProviderEnabled(provider: String)
{
}
override fun onProviderDisabled(provider: String)
{
}
}
答案 2 :(得分:-2)
试试这个
@Override
public void onLocationChanged(Location location) {
try {
if (location != null) {
if (current_lat != null && current_lat > 0) {
latitude = current_lat;
}
if (current_long != null && current_long > 0) {
longitude = current_long;
}
current_lat = location.getLatitude();
current_long = location.getLongitude();
distanceBetweenTwoPoint = getDistance(latitude, longitude, current_lat, current_long);
if ((current_lat > 0 && current_long > 0) && distanceBetweenTwoPoint > IjoomerApplicationConfiguration.track_DistanceBetweenPoints_IN_METERS) {
if (location.hasSpeed()) {
speedInKm = location.getSpeed() * 3.6;
} else {
speedInKm = 0.0;
}
row = new HashMap<String, String>();
row.put(TRACKID, IN_TRACKID + "");
row.put(LATITUDE, current_lat.toString());
row.put(LONGITUDE, current_long.toString());
row.put(SPEED, speedInKm + "");
row.put(TIMESTAMP, System.currentTimeMillis() + "");
row.put(STATUS, status);
distance = distance + (distanceBetweenTwoPoint / 1000);
row.put(DISTANCE, "" + distance);
dataProvider.InsertRow("TrackDetail", row);
row.put(LASTKNOWNLATITUDE, latitude.toString());
row.put(LASTKNOWNLONGITUDE, longitude.toString());
int seconds = (int) ((System.currentTimeMillis() - trackStartTime) / 1000) % 60;
int minutes = (int) (((System.currentTimeMillis() - trackStartTime) / (1000 * 60)) % 60);
int hours = (int) (((System.currentTimeMillis() - trackStartTime) / (1000 * 60 * 60)) % 24);
row.put(DURATION, String.valueOf(hours) + " : " + String.valueOf(minutes) + " : " + String.valueOf(seconds));
setNotification(speedInKm, String.valueOf(hours) + " : " + String.valueOf(minutes) + " : " + String.valueOf(seconds));
if (status.equalsIgnoreCase("1")) {
builder.append("|" + current_lat + "," + current_long);
trackDuration = String.valueOf(hours) + " : " + String.valueOf(minutes) + " : " + String.valueOf(seconds);
if (speedInKm > maxSpeed) {
maxSpeed = speedInKm;
}
totalSpeed = totalSpeed + speedInKm;
++totalTrackPoint;
sendBrodcastToActivity();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}