Geolocation developer
Geolocation is the identification or estimation of the real-world geographic location of an object, such as a radar source, mobile phone, or Internet-connected computer terminal.
In this page only the Website HTML-5 Geolocation is described [1].
The HTML Geolocation option is build-in option in HTML-5.
The purpose of this page is to describe how to implement the Geolocation in JavaScript with jQuery.
Introduction
The HTML-5 Geolocation implementation makes it possible to get the current location of the Website user with the following restrictions:
- The feature is only available in secure contexts (https).
- The user has to give permission to access his personal location (privacy reason).
The functionality has also a limitation:
- A VPN connection hides the real position and replace the location by the VPN instead. This makes the Geolocation useless.
Usage
JavaScript Anonymous function
For me the best way to implement new functionality is by using an anonymous function with all referred variables and methods inside the anonymous function.
Sorry for the users but I am an addict of the C printf/sprintf functions, look for a good implementation on the internet or look at the details below.
<syntaxhighlight lang="javascript" line="line">
/**
* Anonymous function for handling geolocation. * @param object geoLocation Object and Name of the function. * @param object $ jQuery Object. * @param object undefined Prevents the overriding of the undefined. */
(function( geoLocation, $, undefined ) {
'use strict'; geoLocation.versionNumber = "0.1.0.1"; geoLocation.versionDate = "30 Sep 2017";
/** GeoData object. */ var geoData = { available : "geolocation" in navigator, allowed : false, // Has the user consented in the geolocation detection. latitude : -1, longitude : -1, }; /* Verbode developer flag. */ var verbose = false;
/** * Gets the Version number and date of the anonymous function. * @return string number + date. */ geoLocation.version = function() { return sprintf("%s - %s", geoLocation.versionNumber, geoLocation.versionDate) }
/** * Initializes the geoLocation. * @param boolean verboseFlag Optional Verbose flag. * @return void */ geoLocation.init = function( verboseFlag) { 'use strict'; verbose = typeof verboseFlag === 'undefined' ? verbose : verboseFlag;
if ( location.protocol == 'https:' && geoData.available ) { if ( navigator.geolocation ) { navigator.geolocation.getCurrentPosition( geoLocation.successLocation, geoLocation.errorLocation ); return; } } geoLocation.errorLocation(); } // .init
/** * Success Callback function for getting the User location. * When called the geodata object is enriched with allowed, Latitude and Longitude. * @global Object geoData JSO GeoLocation object. * @param Object position JSO with latitude and longitude. * @return void */ geoLocation.successLocation = function( position ) { 'use strict'; var met = "geoLocation.successLocation"; geoData.allowed = true; geoData.latitude = position.coords.latitude; geoData.longitude = position.coords.longitude;
logts( sprintf( logFormatLBW, met, "GeoLocation", "Latitude: " + geoData.latitude + ", Longitude: " + geoData.longitude)); } // .successLocation
/** * Error Callback function for handling errors in GeoLocation. * Sets the global geoData.allowed to false. * @return void */ geoLocation.errorLocation = function() { 'use strict'; var met = "geoLocation.errorLocation";
logts( sprintf( logFormatLBW, met, "GeoLocation", "No position available")); geoData.allowed = false; } // .errorLocation
/** * Checks the given protocol. * For realtime https is necesassry, for local testing http. * Sets the geoData.allowed flag. * @return void */ geoLocation.checkProtocol = function() { if ( location.protocol == 'http:') { geoData.allowed = true; geoData.latitude = 52.414947; geoData.longitude = 7.082583; return false; } return true; } // checkProtocol
/** * Getters for the geoData.allowed, geoData.latitude, geoData.getLongitude * @return boolean geoData.allowed */ geoLocation.getAllowed = function() { return geoData.allowed; } geoLocation.getLatitude = function() { return geoData.latitude; } // . getLatitude geoLocation.getLongitude = function() { return geoData.longitude; } // .getLongitude
} ( window.geoLocation = window.geoLocation || {}, jQuery) ); </syntaxhighlight>
- Line 7 - 10: The anonymous function name and version number and date.
- Line 12 - 18: The geodata object with all important variables,
- available is set true when the geolocation is available in the browser
- allowed is set true when the user has permitted the usage of his location.
- geoLocation.version is a public method for returning the version date and number.
- geoLocation.init is the public method that the user has to call to use the anonymous function.
- geoLocation.successLocation is a public callback function that is called by the geoLocation.init in case of success.
- geoLocation.errorLocation is a public callback function that is called by the geoLocation.init in case of an error/failure.
- geoLocation.checkProtocol is the public function that can be used for testing the anonymous function functionality in a http environment. It sets a dummy location.
Calling anonymous function
To use the anonymous function place the following in the .ready function of your Website.
<syntaxhighlight lang="javascript" line="line"> /**
* jQuery function .ready */
$(document).ready(
function() { 'use strict'; ... // Initializes the geoLocation. geoLocation.init(); ... setTimeout( "bgAuditMonitor()", 3500);
});
/**
* Time delayed Audit monitor call. * The delay is necessary to catch the GeoLocation (only under https protocol). * @global ipAddress, loginID, loginUID * @return void */
function bgAuditMonitor() {
'use strict'; ... // If there is geolocation information if (geoLocation.getAllowed() ) { altert( "Geolocation latitude " + geoLocation.getLatitude() + ", longitude " +geoLocation.getLongitude() ); }
} </syntaxhighlight>
- line 1 - 7: Example lines to implement the jQuery.ready() method.
- line 8 - 9: Calling the anonymous function geoLocation.init() method which will set all necessary variables.
- line 11: Calls the method to show the found geolocation with a timeout because the location determination has a delay itself.
- line 20 - 27: Example setTime method implementation for showing the geolocation.
Details
Detecting Geolocation Availability
First detect if your browser and context support geolocation. Use the following code: <syntaxhighlight lang="javascript" line='line'> if ("geolocation" in navigator) {
/* geolocation is available */
} else {
/* geolocation IS NOT available */
} </syntaxhighlight>
Browser Compatibility
Feature | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|---|
Basic Support | 5.0 | (Yes) | 3.5 | 9 | 10.6 | 5 |
Secure origins only | 50.0 | No support | 55 | No support | 39 | 10 |
Utility/Tools
sprintf
<syntaxhighlight lang="javascript" line="line"> /** Javascript implementation for C/C++ sprintf. Uses InvalidArgumentException and getJSFileLinePos. (since 1.0.6.3). The elements are variable string list with arguments. @return string formatted according to the required format.
- /
function sprintf() {
'use strict'; var i = 0, a, f = arguments[i++], o = [], m, p, c, x, s = ; while (f) { if (m = /^[^\x25]+/.exec(f)) { o.push(m[0]); } else if (m = /^\x25{2}/.exec(f)) { o.push('%'); } else if (m = /^\x25(?:(\d+)\$)?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(f)) { if (((a = arguments[m[1] || i++]) == null) || (a == undefined)) { var as = "", aj = 0, an = arguments.length; for (aj = 0; aj< an; aj++) { as+= arguments[aj] + "; "; } throw(" Too few arguments. Given arguments: " + as); } if (/[^s]/.test(m[7]) && (typeof(a) != 'number')) { // throw('Expecting number but found ' + typeof(a)); throw new InvalidArgumentException("Expecting number but found " + typeof(a) + " " + getJSFileLinePos( new Error().stack, 2) + "."); } switch (m[7]) { case 'b': a = a.toString(2); break; case 'c': a = String.fromCharCode(a); break; case 'd': a = parseInt(a); break; case 'e': a = m[6] ? a.toExponential(m[6]) : a.toExponential(); break; case 'f': a = m[6] ? parseFloat(a).toFixed(m[6]) : parseFloat(a); break; case 'o': a = a.toString(8); break; case 's': a = ((a = String(a)) && m[6] ? a.substring(0, m[6]) : a); break; case 'u': a = Math.abs(a); break; case 'x': a = a.toString(16); break; case 'X': a = a.toString(16).toUpperCase(); break; } a = (/[def]/.test(m[7]) && m[2] && a >= 0 ? '+'+ a : a); c = m[3] ? m[3] == '0' ? '0' : m[3].charAt(1) : ' '; x = m[5] - String(a).length - s.length; p = m[5] ? str_repeat(c, x) : ; o.push(s + (m[4] ? a + p : p + a)); } else {
throw('Huh ?!'); // throw new InvalidArgumentException("Huh ?! " + getJSFileLinePos( new Error().stack, 2) + "."); } f = f.substring(m[0].length); } return o.join();
} // sprintf
/** InvalidArgumentException @param message The String exception-error-message @since 1.0.6.3
- /
function InvalidArgumentException(message) {
this.message = message; // Use V8's native method if available, otherwise fallback if ("captureStackTrace" in Error) Error.captureStackTrace(this, InvalidArgumentException); else this.stack = (new Error()).stack;
} // InvalidArgumentException
InvalidArgumentException.prototype = Object.create(Error.prototype); InvalidArgumentException.prototype.name = "InvalidArgumentException"; InvalidArgumentException.prototype.constructor = InvalidArgumentException;
/** Gets the File-Line-Position of the error location. The function expects the index to be the correct place of the calling function so the search for the error is simplified. See for an example call the function sprintf. The difference between the browsers for a successful implementation almost impossible.. @param es String Exception Stack error (create with 'new Error().stack'). @param index Integer Index of the line in the stack trace containing the error. @since 1.0.6.3
- /
function getJSFileLinePos(es, index) {
'use strict'; var i = typeof index === 'undefined' ? 2 : index; var bi = getBrowserInfo(); var separator = "\n"; var aFLP = es.split(separator); var n = aFLP.length; if (index >= n) { index = n-1; } switch(bi.name.toLowerCase()) { case "safari" : return aFLP[0].trim(); default : return aFLP[index].trim(); } return aFLP[index].trim();
} // getJSFileLinePos </syntaxhighlight>
See also
- GeoLocation, Interesting GeoLocations and other examples.
- Virtual Private Network (VPN), With a VPN, you always remain secure and anonymous on the Internet.
Reference
- ↑ Developer Mozilla, Using Geolocation Developer.