NativeScript / nativescript-geolocation

Geolocation plugin to use for getting current location, monitor movement, etc
Apache License 2.0
139 stars 76 forks source link

Location imprecision #39

Closed echap closed 7 years ago

echap commented 7 years ago

Hi there,

I'm dropping this here : It's really tough to manage GPS options with nativescript-geolocation, for multiple reasons :

First of all, my composer :

 "@angular/common": "2.1.2",
    "@angular/compiler": "2.1.2",
    "@angular/core": "2.1.2",
    "@angular/forms": "2.1.2",
    "@angular/http": "2.1.2",
    "@angular/platform-browser": "2.1.2",
    "@angular/platform-browser-dynamic": "2.1.2",
    "@angular/router": "3.1.2",
    "nativescript-angular": "1.1.3",
    "nativescript-theme-core": "^0.2.1",
    "reflect-metadata": "~0.1.8",
    "rxjs": "5.0.0-beta.12",
    "tns-core-modules": "2.4.0",
    "nativescript-audio": "^2.0.6",
    "nativescript-background-http": "^2.3.0",
    "nativescript-geolocation": "0.0.13",
    "nativescript-google-maps-sdk": "git+https://github.com/hubupfr/nativescript-google-maps-sdk.git",
    "nativescript-google-maps-utils": "git+https://github.com/hubupfr/nativescript-google-maps-utils.git",
    "nativescript-permissions": "^1.2.0",
    "nativescript-phone": "^1.2.0",
    "nativescript-ripple": "^1.0.1",
    "nativescript-snackbar": "^1.1.4",
    "nativescript-swiss-army-knife": "1.0.7",
    "nativescript-telerik-ui": "^1.4.1",
    "nativescript-pdf-view": "^1.2.0",
    "moment": "^2.15.1"

And I'm running it on android

  1. It's not easy to understand how to manage the geolocation.watchLocation() options, and default options - that seems to work - are not suited for precise tracking (I understand that they were written for a scarce location, and it can not cover all case). Maybe would it be a nice idea to add several JSON Options in the docs for different use cases ? (very scarce / scarce / fine with battery concerns / very fine...)

  2. Now that's an issue I guess, let's look at this snippet :

    
    public followLocation(toggle:boolean) {
        if(toggle && !this.watchId) {
            // One service of mine that requests location permission
            this._toolsService.requireGPSPermission().then(() => {
                this.watchId = geolocation.watchLocation(
                    (location) => {
                        //My handling
                        this.updateCameraFromPoint(new Point(location.latitude, location.longitude));
                    },
                    function(e){
                        console.log("Error: " + e.message);
                    },
                    { minimumUpdateTime: 500, updateDistance : 2, maximumAge : 5000 })
    
            });
    
        } else if (!toggle && this.watchId) {
            geolocation.clearWatch(this.watchId);
        }
    }

Looks like promissing. Well no. The fine location of the phone is not even triggered and position update appears every ... lots of seconds.
Now, let's do a little workaround.

public followLocation(toggle:boolean) { if(toggle && !this.watchId) { this._toolsService.requireGPSPermission().then(() => { this.mapView.gMap.setMyLocationEnabled(true); this.mapView.gMap.getUiSettings().setMyLocationButtonEnabled(false); console.log("start watchid"); this.watchId = geolocation.watchLocation( (location) => { this.updateCameraFromPoint(new Point(location.latitude, location.longitude)); }, function(e){ console.log("Error: " + e.message); }, { minimumUpdateTime: 500, updateDistance : 2, maximumAge : 5000 })

        });

    } else if (!toggle && this.watchId) {
        this.mapView.gMap.setMyLocationEnabled(false);
        geolocation.clearWatch(this.watchId);
        console.log("stopping watchid");
    }
}


Looks like nothing changed and I only have launched a location tracking from the very good [google maps SDK](https://github.com/dapriett/nativescript-google-maps-sdk). Surprisingly, now it works perfectly.

My guess is that the options are not working well, and calling `this.mapView.gMap.setMyLocationEnabled(true);` triggers a new set of options for the Location module.

So am I clearly missunderstanding the nativescript-location, or is there some kind of bugs in there ?
nsndeck commented 7 years ago

I've tested this scenario with nativescript-geolocation-demo and everything works fine. I've just changed following code:

export function buttonStartTap(agrs: EventData) {
    watchId = geolocation.watchLocation(
        function (loc) {
            if (loc) {
                model.locations.push(loc);
            }
        },
        function (e) {
            console.log("Error: " + e.message);
        },
        { desiredAccuracy: Accuracy.high, updateDistance: 1, minimumUpdateTime: 500 });
}

After that I've got similar to following result:

[
{
    "latitude": 42.6956606,
    "longitude": 23.3280908,
    "altitude": 597.6010485594966,
    "horizontalAccuracy": 8,
    "verticalAccuracy": 8,
    "speed": 4.200727939605713,
    "direction": 117,
    "timestamp": "2016-12-07T12:03:38.001Z",
    "android": {}
}, {
    "latitude": 42.695638,
    "longitude": 23.3281415,
    "altitude": 597.2515697873325,
    "horizontalAccuracy": 24,
    "verticalAccuracy": 24,
    "speed": 4.230191707611084,
    "direction": 118,
    "timestamp": "2016-12-07T12:03:39.001Z",
    "android": {}
}, {
    "latitude": 42.6956116,
    "longitude": 23.3281892,
    "altitude": 597.2158124215418,
    "horizontalAccuracy": 16,
    "verticalAccuracy": 16,
    "speed": 4.2224040031433105,
    "direction": 124,
    "timestamp": "2016-12-07T12:03:40.001Z",
    "android": {}
}, {
    "latitude": 42.6955881,
    "longitude": 23.3282386,
    "altitude": 597.1697055095312,
    "horizontalAccuracy": 16,
    "verticalAccuracy": 16,
    "speed": 4.209714889526367,
    "direction": 121,
    "timestamp": "2016-12-07T12:03:41.001Z",
    "android": {}
}
]

I believe that it is perfectly fine. Could you please elaborate a little bit what you are trying to achieve?

echap commented 7 years ago

I'm checking this out tonight,

Thanks for your answer :+1:

echap commented 7 years ago

Okay, I've tested it and it seems to be working. So this is actually not a nativescript issue, but the doc seems to be incorrect regarding this point. Regarding to options, documentations refers accuracy to :

(Optional) Specifies desired accuracy in meters. Defaults to DesiredAccuracy.HIGH.

Adding the option desiredAccuracy = Accuracy.high may appear (and appeared to me) as useless since this is supposed to be the default option. But still, it seems that it is not the default option.

Thanks again for this hint that is very helpful to me, maybe documentation should be updated according to this ? Is a fix needed to set accuracty to high by default ?

nsndeck commented 7 years ago

Indeed there is an error in documentation default option for desiredAccuracy is any (COARSE) in terms of meters (300 - could be achieved only by wi-fi and aGPS), while high is 3 meters. The decision behind the default value is that high accuracy requires GPS sensor (which is known as a huge battery drainer).

Documentation will be updated ASAP.

echap commented 7 years ago

Perfect, that would be great. For sure GPS is a battery drainer, but our use is a GPS-like feature, which requires a good precision ;), and we're not the only ones for sure !

nsndeck commented 7 years ago

Docs updated!