I'm working on a project where the user's location is needed. The implementation seems to be working correctly, the user gets a prompt to allow sharing their location and the coordinates are received.
The problem is that those coordinates seem to wildly change based on the device or browser. Three different browsers in the same device provide 3 different coordinates, and not just with my code, the same happens when testing with other sites that provide geolocation like https://my-current-location.com/
Does this mean that the browsers Geolocation API can't be trusted? Is there a better way of obtaining a user's location that's more reliable?
I've tried working with server-side location (IP) and the results were also as bad, at least for the part of the world where this needs to work.
Related
Context
I'm working on an ESP32 device that use WifiManager library to set up the device Wifi. This library just create a Wifi Hotspot who redirect to a basic HTML page. This page will be reachable via a smartphone. I want to know the user location when he visits this HTML page.
My Problem
The problem is, that to see this page, he must be connected to the ESP32 Wifi Hotspot so every solution must work without an Internet connection.
Furthermore, I know that there is this API (HTML5 Geolocation), but it didn't work because the server is hosted locally in HTTP. (And I saw a post that said that it must be connected to Internet).
I have also a size constraint. I'm working on a tiny device with already a lot of code so the solution mustn't be to heavy.
So, is there a way to get a smartphone GPS Location via a Javascript script and without using HTML5 Geolocation and without an Internet connection ?
I don't know why you wouldn't want to use JS. It's the only way you can get information from the client in a web app.
The hurdle is, you usually need HTTPS for such sensitive data to be allowed to be sent by the users browser. But how to set your server up for HTTTPS is not a question for StackOverflow.
Sorry that we can't give you a better answer. If you can't do it native you'll have to work with what you've got.
EDIT:
Some browsers need intenet to verify certificates, can't do anything about that. If you don't control the device -> browser.
I am building a web app which offers users certain unlockable feature at certain locations. And I just realized how easy it is to spoof GPS location. Chrome dev tools even offers GeoLocation custom location override setting under sensors. How can I set effective checks for similar hacks?
UPDATE:
Chrome dev tools Geolocation override outputs accuracy of 150m thus IF I set a threshold i.e 40m accuracy (reject all data with accuracy greater than 40m). then that can account for the easy chrome dev tool hack (which is great for testing)
It's not possible to prevent users from spoofing their location. Even if you could prevent it in the client software (and to be clear, you can't), the user could feed a location in via an external GPS (or simply a serial port driver with spoofed location data).
What you can do is watch for signs of this spoofing. You could put in thresholds for location changes and what not. If someone suddenly appears to move further than is reasonable, you could flag the data as suspicious. This isn't ideal though, as sometimes immediate location updates happen. (Suppose your device was in airplane mode before you took off from one city, and then updated as soon as you took it out of airplane mode. For a short time, the phone thinks it is in one place, and then is immediately transported to the correct place.)
In the end, there's nothing you can reliably do about it, in a generic sense.
I'm a bit confused as to why I would choose to use the limited access Google Maps Geolocation API over the free and (apparently) unlimited navigator.geolocation feature of HTML5?
As far as I can tell the only advantage of the Google version is it's increased support for browsers such as IE8. Am I missing something significant here? Or is there little difference?
On further investigation we noticed that when we used navigator.geolocation in Chrome it actually makes a call to the Google api to get the information (backed up by this answer from 6 years ago). So this begs the question, is it still limited? If so by how much in what period?
The Google Maps Geolocation API is an HTTP endpoint that accepts user-supplied JSON data about nearby Wifi networks and cell towers and produces an estimate of the user's location.
The HTML5 navigator.geolocation object supplies a browser API that does some set of operations and then produces an estimate of the user's location. From the W3C geolocation spec:
The API itself is agnostic of the underlying location information sources. Common sources of location information include Global Positioning System (GPS) and location inferred from network signals such as IP address, RFID, WiFi and Bluetooth MAC addresses, and GSM/CDMA cell IDs, as well as user input.
The navigator.geolocation function may make use of any information available to the browser application, including any information from the device's GPS hardware, if it has any. Of course, it may also make use of any third-party Web APIs (including, possibly, the Google Maps Geolocation API) that can be reached. There is no specified required approach or inputs that must or must be used; the browser can do anything in its power to make a location estimate. It may do a better or worse job than Google's approach, depending on their particular implementations, or the browser may (as you suggest) actually directly use Google's API.
In short, Google's API is a way to ask, "Based on this cell and Wifi info, tell me where I am." The HTML5 API is a way to tell the browser, "You have access to the Internet and all the physical inputs available to my device; find out where I am, somehow."
I'm not surprised to learn that, if no GPS is present, the browser might outsource its geolocation work to a third-party service like Google. Browser vendors are generally interested in making browsers, not writing a robust service to solve the hard problem of transforming cell/Wifi data into location information. Furthermore, it requires a tremendous amount of geospatial data about the locations of various towers and Wifi SSIDs. It would bloat the browser to hold all the information locally, and any attempt for thevendor to host the information remotely would functionally be setting up a competitor to Google's already known-good service.
The HTML5 API is going to trigger a modal popup to ask the user to give permission vs the Google Maps Geolocation API is going to bypass that. The methods themselves to gather location are very similar though the scope is there for HTML5 to go deeper depending how the browser implements it.
Example HTML5 - https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/Using_geolocation
Example Google Maps Geolocation - http://webkay.robinlinus.com/
Also Ref: https://developers.google.com/maps/articles/geolocation
Maps API might give you an option for an older browser that doesn't support HTML5 or of course a non-browser client (native etc)
Maps API will cost you $ after the free daily quota
HTML5 method should be prioritised over others in most cases
I just want to mention that if this is all you need, then no, there is no reason to go with the paid Google service--the spec for that service is basically built into the browser at this point.
The Google Maps API comes with many more features than that, however--things like reverse geocoding, and the full visual tool featureset available with maps.
So yes, getting a user's lat/lon is 'free'--no need to pay for that feature by itself.
In my HTML5 page I would like to retrieve the altitude of the device (I'm testing on my Nexus 5 with Chrome mobile).
As mentioned in HTML5 Geolocation Altitude, the altitude returned by the Geolocation API is always null.
I've read that some native Android apps use different approaches such as pressure sensor (when available). Is it somehow possible in HTML5? Do you have other suggestions?
Accessing barometer information
Sadly as of 2015 it's not possible to access barometer information in a native browser environment. A lot of work has been done on writing sensor API specifications, but as barometers are quite a rare hardware feature still they have not been receiving a lot of attention.
It is however possible to bundle your web application in Cordova and use the barometer plugin for android to access the barometer from your code. This however means that the user has to install your application and this would only work Android.
Using GPS information after all
For the large majority of applications where you need altitude information there is only one possible altitude per coordinate pair (this is for example not true if you wish to determine the level you're at in a building, but current GPS altitude information isn't precise enough for that normally either way). In those cases you can request the GPS location and simply request the altitude from a service with a surface database. Two such services are the Google Elevation API (entire world) or the NED Point Query Service (US only?).
The problem is that if the user denies access to location data, the google map is never initialized.
For Example: http://code.google.com/apis/maps/documentation/javascript/examples/map-geolocation.html
When it asks for permission, say not now. The map will be grey.
What can I do to initialize the map no matter what?
I decided to just set a default center point on the map so that if I get a more specific position, I zoom in there, if not I leave it alone.
Hopefully Mozilla fixes this soon, since the bug has been around nearly a year.
Use a server-side script to do IP address geolocation. This will yield a location in the same country at least. Use the IP address's location as default if the user does not permit geolocation in the browser.
An example web service providing IP geolocation is http://www.geobytes.com/iplocator.htm Google will find many more.