How to use the Geolocation API

Geolocation is a new standard that allow us to identify where a user is located by the use of scripts within the browser.

Geolocation-example

This is particularly useful when we want to offer in our web app local information to the users. Some examples of it could be a web app that tells you where is the nearest bus station, a restaurant or just to know where you are when you get lost in the city. Something that by the way, happens to me a lot.

The first thing you need to know is that the Geolocation API just defines a high-level interface to access the geolocation information, but it is completely agnostic on the system used to obtain that geolocation information.

 

 

There are several ways to get the information like:

  • GPS
  • GSM/CDMA cell IDs
  • IP address

As you can already imagine the accuracy of the results will depend a lot on how the geolocation information is retrieved.

Now that we have a little bit of background, let’s see more in detail what the Geolocation API offer us. The API defines a new interface that is called, not surprisingly, Geolocation. This interface defines three methods:

//Used to retrieve the current geolocation, just one time.
void getCurrentPosition(
     //Callback to receive geolocation info
     in PositionCallback successCallback,
     //Callback to receive errors produced during the call
     in optional PositionErrorCallback errorCallback,
     //Options about the geolocation information to retrieve
     in optional PositionOptions options);

//Used to track the geolocation of the user.
long watchPosition(
     //Callback to receive geolocation info
     in PositionCallback successCallback,
     //Callback to receive errors produced during the call
     in optional PositionErrorCallback errorCallback,
     //Options about the geolocation information to retrieve
     in optional PositionOptions options);

//Used to stop tracking the geolocation of the user.
void clearWatch(
     //id of the watch retrieved with watchPosition
     in long watchId);

At this point you will have already noticed that the method getCurrentPosition does not return any value, this is because the API is asynchronous, so in order to obtain the results we need to implement a callback function (PositionCallback) that will be called once the method has the results.

The other two parameters are optional, they let us to define another callback function to receive any error produced while calling the method and the different options to configure the geolocation information that will be retrieved.

Before we proceed to implement a real example let’s examine the rest of classes used in the API:

// used to receive successful notifications about position requests
interface PositionCallback {
    void handleEvent(in Position position);
}

// used to receive error notifications about position requests
interface PositionErrorCallback {
    void handleEvent(in PositionError error);
} 

// used to specify the options about the geolocation information to retrieve
interface PositionOptions {
    // by default false. Indicates you want to obtain the information with
    // the best accuracy available, even if that consumes more battery or
    // means slower response time.
    attribute boolean enableHighAccuracy;
    
    // expressed in milliseconds
    long timeout;

    // expressed in milliseconds. Indicates you accept a cached value
    // no greater than the specified time. If 0, acquires a new position
    long maximumAge
} 

// used to obtain geolocation position information
interface Position {
    readonly Coordinates coords;
    readonly DOMTimeStamp timestamp;
} 

// used to obtain errors while requesting geolocation information
interface PositionError {
    const unsigned short PERMISSION_DENIED = 1;
    const unsigned short POSITION_UNAVAILABLE = 2;
    const unsigned short TIMEOUT = 3;
    readonly attribute unsigned short code;
    readonly attribute DOMString message;
}

// used to obtain the geolocation position details
interface Coordinates {
    //specified in decimal degrees
    readonly attribute double latitude;
    //specified in decimal degrees
    readonly attribute double longitude;
    // specified in meters
    readonly attribute double? altitude;
    // specified in meters and corresponding to 95% confidence level
    readonly attribute double accuracy;
    // specified in meters and corresponding to 95% confidence level
    readonly attribute double? altitudeAccuracy;
    // specified in degrees, denotes the direction of travel counting
    // clockwise relative to the true north (0º to 360º)
    readonly attribute double? heading;
    // specified in meters per second
    readonly attribute double? speed;
}

Now that we have all info we can start creating a real example, to test them you will need any of the modern browsers that supports this feature like Internet Explorer 9.

<!DOCTYPE html>
<html>
    <head>
        <title>Geolocation example</title>
        <script 
            type="text/javascript" 
            src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0">
        </script>
        <script type="text/javascript">
            var map = null;

            function successCallback(position) {
                // we create the location for the Bing Map
                var userLocation = new Microsoft.Maps.Location(
                    position.coords.latitude,
                    position.coords.longitude);

                // we add the pushpin to the map
                var pin = new Microsoft.Maps.Pushpin(userLocation);
                map.entities.push(pin);

                // refresh the map centering the view on current location
                map.setView({ center: userLocation });

                showMessage("Your location is: " + userLocation.toString());
            }

            function errorCallback(error) {
                var code = error.code;
                var message = "unknown error";
                switch (code) {
                    case 1:
                        message = "permission to geolocate you has been denied";
                        break;
                    case 2:
                        message = "position is not available";
                        break;
                    case 3:
                        message = "geolocation request timed out";
                        break;
                }
                showMessage(message);
            }

            function showMessage(message) {
                var div = document.getElementById("message");
                div.innerHTML = message;
            }

            function getMap() {
                // replace with your own Bing credentials
                var mapOptions = {
                    credentials: "YOUR BING CREDENTIALS",
                    center: new Microsoft.Maps.Location(40.42, -3.8),
                    mapTypeId: Microsoft.Maps.MapTypeId.road,
                    zoom: 16
                }

                // we create the Bing map with a default position
                map = new Microsoft.Maps.Map(document.getElementById("map"), mapOptions);

                // if the browser supports Geolocation we do the request
                if (navigator.geolocation) {
                    var options = {
                        enableHighAccuracy: true,
                        timeout: 2000,
                        maximumAge: 0
                    };

                    navigator.geolocation.getCurrentPosition(
                        successCallback,
                        errorCallback,
                        options);
                }
                else {
                    showError("Your browser does not support geolocation");
                }
            }
        </script>
    </head>
    <body onload="getMap();">
        <div id="map" style="position:relative; width:400px; height:400px;">
        </div>
        <div id="message"></div>
    </body>
</html>

In the above example we have seen:

  • how to request the position of the visitor who is accessing our web page
  • how to load a Bing map using the Bing Maps API and set a pushpin in the map indicating our current location
  • how to handle the errors in the case the geolocation information could not be retrieved.

Nokia Lumia 800

A week ago I bought the new Nokia Lumia 800 and I can already say I love this device.

nokia-lumia-800

 

Once you open the box you will see the phone comes with a soft cover in the same color of the device, people who knows me know I hate covers but this one fits perfectly and I’ve decided to use it myself. You can see the phone with and without the cover in the figures below.

Nokia Lumia 800 with soft cover

Nokia Lumia 800 with soft cover.

Nokia Lumia 800 without soft cover 

Nokia Lumia 800 without soft cover

Another nice surprise is the fast USB charger, instead of having the traditional AC/DC adapter you will find as a charger a small circular piece with a diameter just a little bit bigger than a coin. You can compare it below against 2€, a quarter of dollar and fifty pence.

Nokia Lumia USB charger

The design of the phone is simply gorgeous and solid, the case is built in a single piece of polycarbonate that gets emptied and filled with all the electronic in a later phase. The screen, a very stylish Gorilla glass, is a curved 3.7” capacitive AMOLED with ClearBlack that redefines the concept of the black color.

The Nokia Lumia 800 comes equipped with a 8 megapixel camera with Carl Zeiss optics that provides you with a resolution of 3264 x 2448 pixels, a 2x LED flash, F aperture of 2.2, minimum focus range of 10 cm and focal length of 28.0 mm. The camera also allows you to record 720 HD video.

The phone has other goodness like:

  • GPS
  • WIFI
  • Bluetooth
  • 2 microphones
  • 3D accelerometer
  • Magnetometer Sensor (compass)
  • Proximity sensor
  • Ambient light sensor

You will see some haters say the phone doesn’t come with a dual core and they use it as their argument to dismiss the phone, a dual core is completely useless today in Windows Phone 7.5 devices as the OS is extremely fast and fluid. The single core Qualcomm MSM8255 with a clock rate of 1400 MHz makes the phone and apps perform much better than several dual core devices.

As I said above, the Nokia Lumia 800 comes with the Microsoft OS Windows Phone 7.5 aka “Mango” installed. The OS offers you out of the box among many other things:

  • Microsoft Office Mobile: It allows you to work with your Excel, Word, PowerPoint and OneNote files. Thanks to SharePoint Workspace you can also access to your corporate SharePoint repository.
  • Xbox Live: You can play games with the advantages of the Xbox Live network like achievements, manage your friends and messages, etc.
  • SkyDrive: To have your files synched/backed up in the cloud (25 GB of free space)
  • Zune: To have your music and videos downloaded, streamed or simply synched on the phone
  • Social Networks: Have your LinkedIn, Facebook, Twitter and Live contacts as any regular contact, see their updates, etc..

In addition to this, Nokia has included some exclusive apps like Nokia Music, Nokia Maps and the impressing Nokia Drive that allows you to reach your destinations by car using cartography that can be downloaded, free of charge, for virtually the entire world.

Just to finish you will like to hear that the battery lasts for:

  • 9.5 hours for 3G talk time
  • 335 hours for 3G standby time
  • 55 hours for music playback time
  • 6.5 hours for video playback time

Did I say I love the phone?

Why has my Klout score dropped

This seems to be the question that many Klout users asks themselves since yesterday. The reason is simple: Klout has released a new version of the algorithm to measure the influence to improve their accuracy and transparency.

The algorithm will now track better the quality of your interactions instead of the quantity. According to their official work there are three principles that form the basis of the algorithm to determine your score:

  • How many people you influence
  • How much you influence them and
  • How influential they are.

So, something as having a more accurate system has been transformed in a very negative change because lot of users have seen how their score has dropped.

In my opinion the main error Klout has done is not the change itself as many users suggest, but how to reflect it in the score. They should have played more with the psychology of the people and increase the base of the score like for instance adding 100 points to everybody before apply the change, in that way people would have not seen a drop in their score and their egos would have been safe. I’m being a bit ironic but you get the point.

It is really worrying to see how many people trusts the score reputation indexes as the most important thing in Social Media, which in my opinion it’s plain stupid. Don’t get me wrong, I think any score system that allows you track your progress is good, because it will allow you to measure how you are evolving online. But it can’t become your only point of interest or action plan.

Some of the comments you can see in the Klout blog show the madness that is around the online influence and reputation Look this example

many organizations have coupled economic functions and job-related selection to your scoring system. By making this change, you have negatively impacted the job market

Really? Are there companies hiring based on your Klout score? If that’s the case I truly think it is very worrying where we are heading up.

As I said before in all our tasks it is important to have a way to measure success. So Klout, PeerIndex, TwitterGrader, TunkRank … and all the similar systems that give you an artificial and automatic way to measure influence can be a hint for how you are doing your activities online, but none of them can -neither should- replace how we evaluate the influence of a person. It is just common sense to see how any of these score systems attribute you online influence on subject but make you completely irrelevant on a secondary subject.

Don’t be fooled, B2B decisions are not being significantly influenced by conversations on Facebook or Twitter.

Widget Twitter not found. Root element is missing

I don’t know when the issue started, but today I noticed the Widget Twitter in BlogEngine 2.0 has stopped working.

Instead of displaying the latest tweets, it shows the error “Widget Twitter not found. Root element is missing” as you can see in the image below.

widget twitter not found

 

The error looks a bit weird because I haven’t done any modification lately in my blog that could crash it, in addition if you do a quick research online you will see I’m not the only one suffering the issue. It is like all twitter widgets going mad at the same time.

Fortunately it has a very easy solution, the problem is related to the data feed used to display the latest tweets. So to fix it you only need to go to your folder App_Data, delete the file “twitter_feeds.xml” and force the refresh of your site. Once it loads again it will work as normally.

I hope it helps.

Internet Explorer and Web Standards

Many times I see people complaining about Internet Explorer 9 not rendering properly a “standard” web page, after digging into what the problem can be it normally resumes into two options:

  • The web page is not using the document mode “IE9 standards”.
  • The web page is using conditional comments making use of browser detection instead of feature detection and treats IE9 as IE7 or IE6, very old versions of IE that do not support today standards.

Let’s start with what the IE9 standards mode is.

Internet Explorer is the only browser that offers backward compatibility with older versions of the browser. This is done incorporating the new, plus the older versions of the rendering engine with each release of Internet Explorer.

As a user of IE you only need to press F12 to open the Developer Tools and select what document mode use.

InternetExplorer_document_mode_ie9_standards

This is very powerful because as developers we can decide what version of the IE rendering engine will be used to render the markup of our pages. In the case of Internet Explorer 9, as you have seen in the figure above, we can chose between the next document modes:

  • IE 9 standards: This is the default and latest standards-compliant behavior used to render webs that have a strict or unknown document type.
  • IE 8 standards: This behavior acts as it does IE8.
  • IE 7 standards: This behavior acts as it does IE7.
  • Quirks: This is the oldest behavior that can be used with IE, and applies when rendering a document with no doctype or a quirks doctype. It is similar to the behavior of IE5.

Selecting a different mode will reload the page to render it in the document mode selected, but will not change the user-agent string sent to the website. To do that you can also change the Browser Mode using the developer tools.

Regardless the best practice and my suggestion is to target always the standards and keep our sites upgraded to support them, in the case you have an old site you can’t migrate yet, you don’t need to continue using old versions of IE. You can upgrade to IE9 and use as quick fix the X-UA-Compatible meta tag to set what render engine IE has to use to display properly the page.

It is obvious but worthy to mention that if you use an older document mode as “Quirks mode”, you will use it with its full consequences. This means means that your modern IE9 browser will behave as the old IE5 browser and will not be able to use all the new standards and performance improvements that IE9 includes. You can easily see this by running this code and visualizing it in “Internet Explorer 9 standards” and any other document mode:

   1: <html>
   2:   <head>
   3:     <title>HTML5 Canvas example</title>
   4:     <script>
   5:       function drawCanvas(){
   6:  
   7:         var canvas = document.getElementById('myCanvas');
   8:  
   9:         var context = canvas.getContext('2d');
  10:  
  11:         context.fillRect (128, 25, 100, 100);
  12:       }
  13:     </script>
  14:     <style type="text/css">
  15:       canvas { border: 2px solid black; }
  16:     </style>
  17:   </head>
  18:   <body onload="drawCanvas();">
  19:  
  20:     <canvas id="myCanvas" width="260" height="200">
  21:     The document mode does not support canvas
  22:     </canvas>
  23:  
  24:   </body>
  25: </html>

 

So, if you find your website not rendering properly in IE9, first of all check that the site is being rendered in IE9 standards mode and secondly that you are not using any conditional comments that serve custom code for older versions of IE.

In this article we will not cover best practices on how to use feature detection instead of browser detection bad practices to avoid conditional comments, but I recommend reading the article Same Markup: Writing Cross-Browser Code.

You can read additional information on how internet explorer determines the document mode.