Blog

Create an iphone or android app with geo-location targeting

Hello!

Creating mobile applications can be a grueling process. There are many factors that can complicate the process and it is very specialized. One thing we have been looking at recently is utilizing an AngularJS, Node.js based framework to utilize HTML5, javascript and jQuery based technology to implement mobile applications. Specifically the Apache Cordova framework has proved to be very promising.

The Cordova framework is ideal for a mobile application that is not graphics intensive and one that may provide a more realistic learning curve for a developer that has little to no previous mobile application development experience.

One of the more interesting things we have been looking at is, while using the diverse Cordova plugin library, implementing Geo-location and Geo-targeting features that are built into all IOS and Android phones. Leveraging this with Objective-C as you would in a classic IOS application would prove to be a bit more intensive, which is why the Apache Cordova project has implemented these commonly used features in the form of plugins that you could easily add to your project : http://plugins.cordova.io/#/package/org.apache.cordova.geolocation

So what do we want to do? Well we thought it would be interesting to create an app that detects your current location and checks to see if it is in a predefined area. It also would be helpful to “overlay” a shaded color across the geographic area that we are checking against. Why is this needed? Well lets say you wanted to develop a mobile application that returns specific results (i.e. “stores near me”) based on your current geographic location. That would be useful, especially with the increasing popularity of locale-specific services (think “shop local”).

So how do we do this? Well first we need to be able to detect the end-users current location :

navigator.geolocation.getCurrentPosition(onSuccess, onError);

var onSuccess = function(position) {
    var thelat = position.coords.latitude;
    var thelng = position.coords.longitude;
}
function onError(error) {
    alert('code: '    + error.code    + '\n' +
    'message: ' + error.message + '\n');
}

So what do we have here? Well we are triggering the previously mentioned Cordova plugin in order to pull the end-user’s geographic location. We are then assigning latitude and longitude to defined variables thelat and thelng.

The function triggers subsequent functions if the attempt at getting the location is successful, or if there is an error (for example if the end-user refuses to give the app permissions to grab the geographic location).

Now lets actually interact with the Google map API in order to draw the map based on where the actual end-user is standing (or sitting) :

const USER_LOCATION = new plugin.google.maps.LatLng(thelat, thelng);
var map = plugin.google.maps.Map.getMap(div,{
    'backgroundColor': 'white',
    'mapType': plugin.google.maps.MapTypeId.ROADMAP,
    'controls': {
        'compass': true,
        'myLocationButton': true,
        'indoorPicker': true,
        'zoom': true
    },
    'gestures': {
        'scroll': true,
        'tilt': true,
        'rotate': true,
        'zoom': true
    },
    'camera': {
        'latLng': USER_LOCATION,
        'tilt': 0,
        'zoom': 15,
        'bearing': 50
    }
});

This is actually all very standard Google map API stuff and is already well documented. The variable is what was already pulled, which is the users’ latitude and longitude. Now lets do something interesting. Lets pick a location in our area (in our case, Toronto Canada) and highlight a color based on a series of latitude/longitude points onto the map. We chose a well-known park in Toronto called “Trinity Bellwoods” :

// define area for Trinity
const TRINITY_POINTS = [

        // trinity bellwoods
        new plugin.google.maps.LatLng(43.649772, -79.418183),
        new plugin.google.maps.LatLng(43.650207, -79.415951),
        new plugin.google.maps.LatLng(43.649780, -79.415779),
        new plugin.google.maps.LatLng(43.650090, -79.413902),
        new plugin.google.maps.LatLng(43.649881, -79.413859),
        new plugin.google.maps.LatLng(43.650013, -79.413247),
        new plugin.google.maps.LatLng(43.645751, -79.411520),
        new plugin.google.maps.LatLng(43.645199, -79.414213),
        new plugin.google.maps.LatLng(43.645541, -79.414385),
        new plugin.google.maps.LatLng(43.645409, -79.415125),
        new plugin.google.maps.LatLng(43.647303, -79.415865),
        new plugin.google.maps.LatLng(43.647365, -79.415522),
        new plugin.google.maps.LatLng(43.648949, -79.416155),
        new plugin.google.maps.LatLng(43.648996, -79.416638),
        new plugin.google.maps.LatLng(43.649151, -79.417163),
        new plugin.google.maps.LatLng(43.649050, -79.417796)*/

    ];

map.addPolygon({
        'points': TRINITY_POINTS,
        'strokeColor' : '#AA00FF',
        'strokeWidth': 5,
        'fillColor' : '#880000'
    }, function(polygon) {
        map.animateCamera({
            'target': polygon.getPoints()
        });
     });
};

What the above will do is draw in a shaded area with HTML color code #AA00FF from each of the latitude/longitude points defined in the array above. What you’ll get is something very similar to the screenshot at the top of this post.

Finally what we want to do is actually check if the end-user is within that defined area and return a “true” or “false” based on that condition. What we could do is expand on those true/false conditions to do many additional functions and operations to expand and produce a very dynamic application that could potentially be very useful, depending on the objective.

What we did was we found an open source javascript library that can take a single latitude / longitude point and “check” if that point is within a defined area. You can see the library by clicking here. You can include this library in any javascript project you might be working on, not just Apache Cordova.

So what you do is then define the same latitude/longitude points that we did in the Trinity bellwoods example above, as the area to “check”

var isthere = geolib.isPointInside(
    {latitude: thelat, longitude: thelng},
    [

        // trinity bellwoods park
        {latitude: 43.649772, longitude: -79.418183},
        {latitude: 43.650207, longitude: -79.415951},
        {latitude: 43.649780, longitude: -79.415779},
        {latitude: 43.650090, longitude: -79.413902},
        {latitude: 43.649881, longitude: -79.413859},
        {latitude: 43.650013, longitude: -79.413247},
        {latitude: 43.645199, longitude: -79.414213},
        {latitude: 43.649780, longitude: -79.415779},
        {latitude: 43.645541, longitude: -79.414385},
        {latitude: 43.645409, longitude: -79.415125},
        {latitude: 43.647303, longitude: -79.415865},
        {latitude: 43.647365, longitude: -79.415522},
        {latitude: 43.648949, longitude: -79.416155},
        {latitude: 43.648996, longitude: -79.416638},
        {latitude: 43.649151, longitude: -79.417163},
        {latitude: 43.649050, longitude: -79.417796}

    ]
);

alert('is there : ' + isthere);

After loading the geolib.js library from the Github link above, you can use the geolib functions. What we did was we assign the return of the geolib.isPointInside function to a variable called isthere. The variables passed to the functions are the end-users actual geolocation and then the points that define the area of Trinity Bellwoods in Toronto. At the bottom of the snippet is a javascript alert dialog box that outputs whether the variable is “true” or “false” (i.e. in the park geographically or not).

Pretty straightforward, right?