Question

I am trying to parse a kml file to calculate the speed between two adjacent points with the below algorithm (similar to what myTracks Android app does)

public double calculateSpeed(Location prev, Location curr) {

    double deltaDistance = curr.distanceTo(prev);
    double deltaTime = (curr.getTime() - prev.getTime()) / 1000.0;
    double speedInMph = deltaDistance / deltaTime * 2.2369;
    return speedInMph;
}

Code to initialize the location updates:

locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);         
Criteria criteria = new Criteria();         
provider = locationManager.getBestProvider(criteria, false);
locationManager.requestLocationUpdates(provider,1000,5,locationListener);

Links for sample kml file and the log file:

https://dl.dropboxusercontent.com/u/29927114/kml/doc.kml https://dl.dropboxusercontent.com/u/29927114/kml/Log.txt

But my problem is that sometimes the values are coming incorrect.

For eg: in the below log the Speed values are coming as 74, 73, 71, 39, 97, 75, 74 and 22, 22, 10, 3085, 20 , 20. Except the highlighted deviated values the remaining values look correct. Is there a way to find/discard these values or there is a fundamental flaw in my algorithm?

05-02 09:08:10.657: D/KMLParser(11545): Attributes: when: 2014-04-30T17:03:32.070Z
05-02 09:08:10.657: D/KMLParser(11545): Attributes: gx:coord: -1.40748616 52.13896311 175.0
05-02 09:08:10.658: I/KMLParser(11545): 1. -1.40783922, 52.13916636   2. -1.40748616, 52.13896311
05-02 09:08:10.658: I/KMLParser(11545): Dist = 33.102333068847656, Time = 0.999 mps = 74.1207295712766
05-02 09:08:10.658: E/KMLParser(11545): Index = 2, Speed = 74.0
05-02 09:08:10.658: D/KMLParser(11545): Attributes: when: 2014-04-30T17:03:33.073Z
05-02 09:08:10.658: D/KMLParser(11545): Attributes: gx:coord: -1.4071429 52.13875571 174.0
05-02 09:08:10.659: I/KMLParser(11545): 1. -1.40748616, 52.13896311   2. -1.4071429, 52.13875571
05-02 09:08:10.659: I/KMLParser(11545): Dist = 32.93754959106445, Time = 1.003 mph = 73.45763178489739
05-02 09:08:10.659: E/KMLParser(11545): Index = 3, Speed = 73.0
05-02 09:08:10.659: D/KMLParser(11545): Attributes: when: 2014-04-30T17:03:34.073Z
05-02 09:08:10.659: D/KMLParser(11545): Attributes: gx:coord: -1.40680545 52.13855525 173.0
05-02 09:08:10.660: I/KMLParser(11545): 1. -1.4071429, 52.13875571   2. -1.40680545, 52.13855525
05-02 09:08:10.660: I/KMLParser(11545): Dist = 32.11391067504883, Time = 1.0 mph = 71.83560678901672
05-02 09:08:10.660: E/KMLParser(11545): Index = 4, Speed = 71.0
05-02 09:08:10.660: D/KMLParser(11545): Attributes: when: 2014-04-30T17:03:35.073Z
05-02 09:08:10.660: D/KMLParser(11545): Attributes: gx:coord: -1.40663056 52.13844134 173.0
05-02 09:08:10.661: I/KMLParser(11545): 1. -1.40680545, 52.13855525   2. -1.40663056, 52.13844134
05-02 09:08:10.661: I/KMLParser(11545): Dist = 17.43634796142578, Time = 1.0 mph = 39.00336675491333
05-02 09:08:10.661: E/KMLParser(11545): Index = 5, Speed = 39.0
05-02 09:08:10.661: D/KMLParser(11545): Attributes: when: 2014-04-30T17:03:36.601Z
05-02 09:08:10.661: D/KMLParser(11545): Attributes: gx:coord: -1.40592909 52.13802792 172.0
05-02 09:08:10.662: I/KMLParser(11545): 1. -1.40663056, 52.13844134   2. -1.40592909, 52.13802792
05-02 09:08:10.662: I/KMLParser(11545): Dist = 66.50345611572266, Time = 1.528 mph = 97.35705561862565
05-02 09:08:10.662: E/KMLParser(11545): Index = 6, Speed = 97.0
05-02 09:08:10.662: D/KMLParser(11545): Attributes: when: 2014-04-30T17:03:37.601Z
05-02 09:08:10.662: D/KMLParser(11545): Attributes: gx:coord: -1.40557412 52.13781792 172.0
05-02 09:08:10.663: I/KMLParser(11545): 1. -1.40592909, 52.13802792   2. -1.40557412, 52.13781792
05-02 09:08:10.663: I/KMLParser(11545): Dist = 33.71452713012695, Time = 1.0 mph = 75.41602573738098
05-02 09:08:10.663: E/KMLParser(11545): Index = 7, Speed = 75.0
05-02 09:08:10.663: D/KMLParser(11545): Attributes: when: 2014-04-30T17:03:38.600Z
05-02 09:08:10.663: D/KMLParser(11545): Attributes: gx:coord: -1.40522992 52.13760866 172.0
05-02 09:08:10.663: I/KMLParser(11545): 1. -1.40557412, 52.13781792   2. -1.40522992, 52.13760866
05-02 09:08:10.663: I/KMLParser(11545): Dist = 33.12906265258789, Time = 0.999 mph = 74.18058082840226
05-02 09:08:10.663: E/KMLParser(11545): Index = 8, Speed = 74.0

05-02 09:08:11.551: E/KMLParser(11545): Index = 1035, Speed = 19.0
05-02 09:08:11.551: D/KMLParser(11545): Attributes: when: 2014-04-30T17:22:54.642Z
05-02 09:08:11.552: D/KMLParser(11545): Attributes: gx:coord: -1.20618821 51.89674183 128.0
05-02 09:08:11.556: I/KMLParser(11545): 1. -1.20617359, 51.89683068   2. -1.20618821, 51.89674183
05-02 09:08:11.556: I/KMLParser(11545): Dist = 9.93702220916748, Time = 0.998 mph = 22.272670320327393
05-02 09:08:11.556: E/KMLParser(11545): Index = 1036, Speed = 22.0
05-02 09:08:11.556: D/KMLParser(11545): Attributes: when: 2014-04-30T17:22:55.642Z
05-02 09:08:11.556: D/KMLParser(11545): Attributes: gx:coord: -1.20618857 51.89665264 129.0
05-02 09:08:11.557: I/KMLParser(11545): 1. -1.20618821, 51.89674183   2. -1.20618857, 51.89665264
05-02 09:08:11.557: I/KMLParser(11545): Dist = 9.92379093170166, Time = 1.0 mph = 22.198527935123444
05-02 09:08:11.557: E/KMLParser(11545): Index = 1037, Speed = 22.0
05-02 09:08:11.557: D/KMLParser(11545): Attributes: when: 2014-04-30T17:22:57.636Z
05-02 09:08:11.557: D/KMLParser(11545): Attributes: gx:coord: -1.20619499 51.89656647 129.0
05-02 09:08:11.558: I/KMLParser(11545): 1. -1.20618857, 51.89665264   2. -1.20619499, 51.89656647
05-02 09:08:11.558: I/KMLParser(11545): Dist = 9.597917556762695, Time = 1.994 mph = 10.767092167864831
05-02 09:08:11.558: E/KMLParser(11545): Index = 1038, Speed = 10.0
05-02 09:08:11.558: D/KMLParser(11545): Attributes: when: 2014-04-30T17:22:57.643Z
05-02 09:08:11.558: D/KMLParser(11545): Attributes: gx:coord: -1.20619719 51.89647971 130.0
05-02 09:08:11.559: I/KMLParser(11545): 1. -1.20619499, 51.89656647   2. -1.20619719, 51.89647971
05-02 09:08:11.559: I/KMLParser(11545): Dist = 9.654572486877441, Time = 0.007 mph = 3085.1875994137354
05-02 09:08:11.559: E/KMLParser(11545): Index = 1039, Speed = 3085.0
05-02 09:08:11.559: D/KMLParser(11545): Attributes: when: 2014-04-30T17:22:58.639Z
05-02 09:08:11.559: D/KMLParser(11545): Attributes: gx:coord: -1.20620314 51.89639872 130.0
05-02 09:08:11.560: I/KMLParser(11545): 1. -1.20619719, 51.89647971   2. -1.20620314, 51.89639872
05-02 09:08:11.560: I/KMLParser(11545): Dist = 9.020686149597168, Time = 0.996 mph = 20.25941048999388
05-02 09:08:11.560: E/KMLParser(11545): Index = 1040, Speed = 20.0
05-02 09:08:11.560: D/KMLParser(11545): Attributes: when: 2014-04-30T17:22:59.638Z
05-02 09:08:11.560: D/KMLParser(11545): Attributes: gx:coord: -1.2062078 51.89631631 129.0
05-02 09:08:11.560: I/KMLParser(11545): 1. -1.20620314, 51.89639872   2. -1.2062078, 51.89631631
05-02 09:08:11.560: I/KMLParser(11545): Dist = 9.174989700317383, Time = 0.999 mph = 20.54407853917913
05-02 09:08:11.560: E/KMLParser(11545): Index = 1041, Speed = 20.0
Was it helpful?

Solution

I think the problem comes of small inaccuracy in the GPS logs. As you take points that are very close from each other (30 - 60 meters) a small variation can nearly double the speed.

I believe you could clean your data this way:

public double calculateSpeed(Location prev, Location curr, double lastSpeed) {

    double deltaDistance = curr.distanceTo(prev);
    double deltaTime = (curr.getTime() - prev.getTime()) / 1000.0;
    double speedInMph = deltaDistance / deltaTime * 2.2369;

    if (abs(speedInMph - lastSpeed) > lastSpeed/100*20) {  //This check that the speed difference is no bigger than 20% of the last known valid speed
        return -9999; //Or anything that make signal a problem
    }


    return speedInMph;
}

So by adding as input the last known speed, you can control that your calculated speed is not crazy. However, even if this might work, you would maybe have even better results by using a moving average. The problem with this is that it would maybe show strange behaviour if the car suddenly brakes for instance, as it might consider this as a problem in the data.

The best solution I see is doing as follow:

  1. Do as you did before
  2. Write another code that takes as input the output of pt.1 This code will locate and remove the irregularities in speed -> So if the cars brakes and stay for a while at 0 mph, then it is not an isolated crazy speed and the code will not remove it.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top