navigator.geolocation.watchPosition only return each 100 m

theva picture theva · Jan 1, 2017 · Viewed 13.4k times · Source

I am using navigator.geolocation.watchPosition in my react native project to paint a path on a map while the user is moving. I noticed that the return frequency is quite low for this function. I taught it was the frequency at least, when I tested using the iOS emulator and the "freeway drive" mode in the gps emulator. Now when I tested with "city run" instead, I can see that the return frequency of the position is not dependent on some time interval, but instead on a distance... The function is returning its position once each 100 meters, no matter how long it took for the position to change that much.

Why is it like this? Is this a expected behaviour? I don't know if it has to do with the iOS emulator or with my code, but I would really like the position to be more precise, I want it to return as often as possible.

componentDidMount() {
    const { region } = this.state;

    navigator.geolocation.getCurrentPosition(
        (position) => {
          this.setState({position});
        },
        (error) => alert(JSON.stringify(error)),
        {enableHighAccuracy: true, timeout: 20000, maximumAge: 1000}
    );

    this.watchID = navigator.geolocation.watchPosition((lastPosition) => {
        var { distanceTotal, record } = this.state;
        this.setState({lastPosition});
        if(record) {
            var newLatLng = {latitude:lastPosition.coords.latitude, longitude: lastPosition.coords.longitude};

            this.setState({ track: this.state.track.concat([newLatLng]) });
            this.setState({ distanceTotal: (distanceTotal + this.calcDistance(newLatLng)) });
            this.setState({ prevLatLng: newLatLng });
        }
    },
    (error) => alert(JSON.stringify(error)),
    {enableHighAccuracy: true, timeout: 20000, maximumAge: 0});
} 

Answer

Kimmen picture Kimmen · Feb 1, 2017

There's an option you can set that is called distanceFilter which you set the accuracy in meters. It's stated in the documentation for geolocation but not explained what it does or the default value. If you take a look at the source code at github the default is set to 100 meters, which explains your behavior.

If you want 1 meter accuracy you set the options as: {enableHighAccuracy: true, timeout: 20000, maximumAge: 0, distanceFilter: 1}