In the rapidly evolving data analytics space that is driving renewed IT and marketing spend, one of the key metrics is end user tracking is…

  • Who are you (Identity)?
  • What are you entitled to (Access)?
  • How are you (Wellness)?
  • Which things draw/drive your attention (Behavior Patterns)
  • “Where are you?” (Location)
  • Every location based app out there wants your mobile phone or wearable to tell it where you are. This is achieved with a small bit of technology called “geolocation.” “Where are you?” –  is what we’ll focus on in this blog post.

    How does geolocation work?

    In general, mobile apps with geolocation capabilities do two things:

  • They report your location to other users
  • They associate real-world locations to things like events, points of interests (ATMs, stores, restaurants, etc) to your location.
  • There are two mechanisms currently used to determine geolocation. One is based on radio frequency location and second on IP/Mac address type information.

    Geolocation for mobile and GPS traditionally use radio frequency (RF) location methods, for example Time Difference Of Arrival (TDOA) for precision. TDOA systems often utilize mapping displays or other geographic information systems.

    firedepartment-screen1

    Smartphones have a richer geolocation experience than desktops because of the real-time feedback services to the location. Usually they have an embedded GPS chip which uses satellite data to calculate your exact position, which services such as Google Maps can then map. When a GPS signal is unavailable, geolocation apps can use information from cell towers to triangulate your approximate position. Some hybrid techniques have evolved recently like Assisted GPS (A-GPS) for higher accuracy.

    Internet and computer geolocation can be performed by associating a geographic location with the Internet Protocol (IP) address, MAC address, RFID, embedded hardware article/software number.

    StrongLoop_Pic

    Geolocation usually works by automatically looking up an IP address on a WHOIS service and retrieving the registrant’s physical address.

    IP address location data can include information such as country, region, city, postal/zip code, latitude, longitude and timezone.

    In this post we won’t cover native (iPhone, Android) navigator capabilities, instead we’ll focus on a more generic solution for JavaScript developers.

    How can I get started as a JavaScript developer ?

    Most modern browsers like Firefox, Internet Explorer, Safari, Chrome, and Opera have geolocation API support. Chrome even has support for the World Geodetic System (WGS 84) navigation system, which is the reference coordinate system for GPS.

    These geolocation APIs center around a new property on the global navigator object: navigator.geolocation. The API is designed to enable both “one-shot” position requests and repeated position updates, as well as the ability to explicitly query the cached positions. Location information is represented by latitude and longitude coordinates.

    The simplest use of the geolocation API looks like this:

    function showMap(position) {
    // Show a map centered at (position.coords.latitude, position.coords.longitude).
    }
    
    // Snapshot position request.
    navigator.geolocation.getCurrentPosition(showMap);
    

    As you’d expect, privacy is a first class citizen for the geolocation API. What this means is that geolocation support is “opt-in” by default. The browser will never force you to reveal your current physical location to a remote server without explicit permission. The user experience may differ slightly from browser to browser, but everyone has seen pop-up messages like this:

    image006

    Calling the getCurrentPosition() function of the geolocation API will cause the browser to pop up an “infobar” at the top of the browser window providing the website name that is seeking to know your location. Thus letting you choose (opt-in) to share your location or deny sharing and allowing the browser to save your opt-in choice (share/don’t share).

    A similar workflow is seen for mobile apps as well, but in this case the requester is the WiFi radio locator instead of the browser. Device notifications are similarly specific to platform and use mobile backend services like APN for iOS as an example

    1-pop-up

    Codewise, we just invoked a single function call which takes a callback function (which is called show_map). The call to getCurrentPosition() returns immediately, but without access to the user’s location. Access to the location/position data is in the callback function. The callback function looks like this:

    function show_map(position) {
     var latitude = position.coords.latitude;
     var longitude = position.coords.longitude;
     // let's show a map or do something interesting!
    }
    

    You can find comprehensive examples of recursive location/position updates, error handling, caching and more on W3C spec for Geolocation API.

    Can I get geolocation served as an API or a backend service  ?

    Increasingly mobile and app services are being rendered through universal backends providing device/platform/form factor independence on the client side. These backends are referred to as BaaS (Backend-as-a-Service) or mBaaS (mobile Backend-as-a-Service) in the case of mobile specific services that are exposed. Node.js has become technology of choice to build extremely fast, scalable and lightweight mBaaS primarily due to REST based data transfer, a huge ecosystem of data connectors and integration with frontend JavaScript stacks like Angular and Backbone. Also working in Node.js favor is its ability to interoperate using JSON models with NoSQL databases like MongoDB.

    LoopBack is the leading open source Node.js framework built on top of express.js middleware that can help you build your own mBaaS using model-driven API development. In addition to built in capabilities like ORM, object discovery, offline sync, replication and multi-channel (iOS, Android, Angular, HTML5) SDKs; geolocation and push notifications are available out of box. Loopback uses isomorphic JavaScript, essentially RPC/remoting capabilities and browersify support to share definition and state of server side JavaScript/JSON data models written in Node.js with frontend JavaScript stacks.

    Let’s build geolocation as a service!

    First, install the StrongLoop package

    $ npm install -g strongloop
    

    We will now get an example LoopBack app with pre-wired location and push notification services

    $ slc loopback:example
    

    We are then prompted by the LoopBack generator for a project structure. I am choosing the project name as Rental_Car_App

    [?] Enter a directory name where to create the project: Rental_Car_App
    

    The generator will pull down the required npm modules for scaffolding, data connection, API documentation and testing. Now we can simply change directory to the project

    $ cd Rental_Car_App/
    

    And boot up the API application using:

    $ slc run
    supervisor running without clustering (unsupervised)
    Using the memory connector.
    To specify another connector:
     `DB=oracle node .` or `DB=oracle slc run .`
     `DB=mongodb node .` or `DB=mongodb slc run .`
     `DB=mysql node .` or `DB=mysql slc run .`
    Started the import of sample data.
    Browse your REST API at http://localhost:3000/explorer
    Web server listening at: http://localhost:3000/
    

    For more advanced runtime commands like running daemonized, in-cluster mode, with log aggregation, with monitoring et all, please checkout the StrongLoop Controller and Perfromance Monitoring pages.

    By default the Loopback API Server instance connects to an in-memory object store. You have options of connecting to relational datasources (Oracle, MySQL, PostgreSQL or SQL Server), NoSQL databases like MongoDB, services like REST and SOAP, or proprietary backends like Sharepoint, SAP, or ATG.

    Opening a browser and running the URL http://localhost:3000/explorer, we instantaneously get our APIs running in Swagger 2.0 interface with RPC/remoting built-in from the browser to the Node.js server.

    Screen Shot 2014-10-02 at 7.16.07 AM

    Here we see that APIs have been auto-created for Car Rental services, which help detect cars, inventory, locations for dealerships, etc along with automatic API end-points for every CRUD and custom operations.

    Screen Shot 2014-10-02 at 7.21.40 AM

    Clicking on the Location API, we can see all endpoints. Of particular interest are “GET /Locations” and “GET /Locations/nearby”.

    We can click on the “Try it out !” button under both these API endpoints. GET /Locations returns us a list of all the rental car center/dealership locations.

    Screen Shot 2014-10-02 at 7.23.44 AM

    In each physical location adhering to  the location model schema, following attributes are found returned as JSON objects. See one of the records below:

    {
       "id": "100",
       "street": "1659 Airport Blvd",
       "city": "San Jose",
       "name": "Dollar Rent A Car",
       "geo": {
         "lat": 37.365759,
         "lng": -121.9233569
       },
       "state": "CA",
       "country": "US",
       "phone": "(866) 434-2226"
     },
    

    For more on modeling from scratch, visit http://docs.strongloop.com/display/LB/Getting+started+with+LoopBack

    We can see that the geolocation is being calculated by the server and would be great we query nearby rental car centers based on a particular geolocation.

    Screen Shot 2014-10-02 at 7.36.18 AM

    Here I am passing a geolocation as a query in terms of latitude and longitude and a Distance To query parameter, which is “5 miles” from that geopoint. In the result set, I get back a list of all rental car centers in a 5 mile radius from the specified lat/long.

    WOW ! that was slick, but how much code do I need to write ?

    Not much. Once location is embedded in a model, Loopback framework takes care of all the compute, filter, pagination,  middleware wiring and rendering. Here is the code snippet that makes geopoint work for finding coffee shops near a physical location (lat/long pair).

    var here = new GeoPoint({lat: 10.32424, lng: 5.84978});
    CoffeeShop.find( {where: {location: {near: here}}, limit:3}, function(err, nearbyShops) {
    console.info(nearbyShops); // [CoffeeShop, ...]
    });
    

    geoPoint.distanceBetween(pointA, pointB, options)

    Determine the spherical distance between two GeoPoints.

    geoPoint.distanceTo(point, options)

    Determine the spherical distance to the given point. Example:

    var here = new GeoPoint({lat: 10, lng: 10});
    var there = new GeoPoint({lat: 5, lng: 5});
    GeoPoint.distanceBetween(here, there, {type: 'miles'}) // 438
    

    geoPoint.toString()

    Simple serialization.

    For more details please check out http://docs.strongloop.com/display/LB/GeoPoint+class.

    These APIs now can be surfaced into a mobile or JavaScript app using out of box client SDKs or direct remoting calls. Below is an example of the Rental Car app using these backend APIs.

    Screen Shot 2014-10-03 at 8.17.20 AM