Two-Minute Tutorial 4 Part 1 Map Plugin V2

TMT4 P1 jQuery Mobile Plugin for Google Maps: Route Finder App with jQuery Google Maps Plugin Version 2 (Version 3 is now available – read below)

November 14, 2011 The new tutorial (HERE) uses the latest versions of AppLaud and jQuery Google Maps Plugin Version 3. To get the benefit of the latest support from PhoneGap and jQuery it is recommended to use the new tutorial.

This tutorial uses jQuery Google Maps Plugin Version 2.

jQuery Mobile / Google Maps on Android

This Two-Minute Tutorial (TMT4 Part1 Version 1) shows how to use a plugin with AppLaudto extend the functionality of jQuery Mobile available to an Android mobile web app. The plugin acts as a wrapper for google maps, providing a simplified API for accessing Google Maps from jQuery Mobile: jQuery Google Maps plugin by Johan Säll Larsson. The sample app demonstrates an easy way to show a dynamic route map in a mobile web app and provide interactive directions using PhoneGap’s geolocation functionality.

jQuery Google Maps Plugin (UI and Mobile)

The jQuery Google Maps plugin v. 2 is a jQuery plugin written to take away some of the headaches from working with the Google Map v3 API. Instead of having to use Google event listeners for simple events like tap, you can use jQuery touch events on the map and markers. It is also very flexible, highly customizable, lightweight (< 4KB) and works out of the box with jQuery Mobile. The plugin is well-documented and supported, and provides the most common functionality available from Google maps. The jQuery Google Maps plugin documentation integrates links to google maps APIs, classes and methods, shortening the learning curve for including google maps in a mobile web app.

  • jquery-ui-map documentation
  • jquery-ui-map mobile examples
  • jquery-ui-map forum
  • jquery-ui-map download

Sample App Summary

Use dynamic location to provide map and directions to business location using Google Maps and PhoneGap geolocation:

  • small map showing the location of a business on home screen
  • full screen google interactive route map: current location to business location
  • interactive written directions using google maps

Both maps and the directions are identical in every way (look and functionality) to Google’s version 3 maps, because they are google maps!

Prerequisites

  • Installation of the latest MDS AppLaud plugin, see Get Started
  • Complete TMT0 or equivalent (create project, edit files, run app on device or AVD)

Prep

  • Download the attached zip file tmt4part1.zip
    • /src directory contains:
      • index.html – jQuery Mobile included, all pages and divs needed for app
      • mapapp.js – skeleton javascript file, add javascript code to it in tutorial
      • mapapp.complete.js – the complete javascript file, provided for convenience
      • mapapp.css – important styling for map display
    • /jquery.ui.map contains:
      • jquery.ui.map.min.js – minified, version 2 plugin (use for market version)
      • jquery.ui.map.js – non-minified, version 2 plugin (use for development)
  • Alternative method: include the jquery.ui.map plugin from a server (see step 2 below)

Recommended Reading

  • The jQuery Google Maps plugin documentation
    • Complete API documentation with links to all google maps classes and methods
  • jQuery Mobile Docs and Demos
  • Google Maps Geocoding – post on MDS’ forum titled “How To: Geocoding, Google Maps…” talks about geocoding with references to Google’s excellent documentation on the subject

1. Create a new AppLaud project

Using the project creation wizard, create a new project that includes:

  • Built-In PhoneGap
  • jQuery Mobile Libraries
  • Project Contents: locate the /src directory (see Prep step above)

Finish creating the project in the second window: fill in project name, etc. Upon completion the new project’s /assets/www/ directory should appear as below.

2. Add Google Maps v3 and the jQuery Google Maps plugin to the project

Adding a jQuery Plugin is usually as simple as including a javascript file in your html file. The reference to the plugin can point to a local copy or reference the file on a server.

To use the plugin javascript locally, import the plugin files:

  • Right click on the /assets/www/jquery.mobile directory in the project and select Import…
  • Navigate to the directory /jquery.ui.map (see Prep step above)
  • Select the files jquery.ui.map.min.js and jquery.ui.map.js and finish importing

Edit index.html to include google maps javascript before mapapp.js:

<script type=”text/javascript” src=”http://maps.google.com/maps/api/js?sensor=false”></script>
Edit index.html to include the javascript file, before the mapapp.js include line, after google maps javascript:

<script type=”text/javascript” src=”jquery.mobile/jquery.ui.map.js”></script>
Alternate method: reference the files on a server by adding the following to index.html:

<script type=”text/javascript” src=”http://jquery-ui-map.googlecode.com/svn/tags/2.0/ui/jquery.ui.map.min.js”></script>

Sanity test: The app can be deployed at this point, before any javascript is added, and should look like the following image. The Map button in the toolbar near the bottom can be used to navigate to the (empty) map and directions pages.

3. The Business Location (Destination)

The object mapdata defines the route destination. In the sample app, the location of the fictional business is in Stockholm, Sweden. Google maps uses a LatLng object to hold coordinates, created as shown below.

var mapdata = { destination: new google.maps.LatLng(59.3327881, 18.064488100000062) };
Note: Recommended method for implementing this app: use the default coordinates provided for a first run/sanity test. Once everything is running as desired, custom coordinates can be substituted. A convenient website for finding coordinates anywhere in the world is Get Lat Lon by Simon Willison.

Further Note: Want to use a street address instead? See forum post “How To: Geocoding, Google Maps…”

4. Create Small Map on Home Page

The API for the jQuery Google Maps plugin is defined by the wrapper method .gmap() used with a DOM element id (div). The home page, defined in index.html with jQuery data types: <div data-role=”page” data-theme=”c” id=”page-home”> creates the element: <div “id=”map_square”></div> on the page where the map will go.

Add the following code block to mapapp.js.

// Start page
$(‘#page-home’).live(“pagecreate”, function() {
$(‘#map_square’).gmap(
{ ‘center’ : mapdata.destination,
‘zoom’ : 12,
‘mapTypeControl’ : false,
‘navigationControl’ : false,
‘streetViewControl’ : false,
‘callback’ : function(map) {
$(‘#map_square’).gmap(‘addMarker’,
{ ‘position’ : map.getCenter(),
‘animation’ : google.maps.Animation.DROP
});
}
});
$(‘#map_square’).click( function() {
$.mobile.changePage(‘#page-map’, ‘slide’);
});
});
Alternative method: Modify index.html to include mapapp.complete.js instead of mapapp.js. The file mapapp.complete.js contains all the javascript for the app.

The code above uses map_square to create the small map on the home page, centered at the business location (mapdata.destination).  Documentation for all google map options can be found here.

The callback function uses .gmap() with the method  ‘addMarker’ to add a marker at the location after the map is created. More information on google markers here.

The area defined by map_square is then bound to the ‘click’ or ‘tap’ event handler, which will navigate to the page containing the full map.

For the desired layout and appearance, css styling and jQuery Mobile features are used in index.html and mapapp.css to control the size and location of the map.

5. Create the main map and directions page

Add the following code to the end mapapp.js.

//Create the fullscreen map, request display of directions
var toggleval = true; // used for test case: static locations
$(‘.refresh’).live(“click”, function() {
$(‘#map_canvas’).gmap({
‘callback’ : function(map) {
// START: Tracking location with test lat/long coordinates
// Toggle between two origins to test refresh, force new route to be calculated
var position = {};
if (toggleval) {
toggleval = false;
position = { coords: { latitude: 57.6969943, longitude: 11.9865 } };//Gothenburg
} else {
toggleval = true;
position = { coords: { latitude: 58.5365967, longitude: 15.0373319 } };//Motala
}
$(‘#map_canvas’).gmap(‘displayDirections’,
{ ‘origin’ : new google.maps.LatLng(position.coords.latitude,
position.coords.longitude),
‘destination’ : mapdata.destination,
‘travelMode’ : google.maps.DirectionsTravelMode.DRIVING},
{ ‘panel’ : document.getElementById(‘dir_panel’)},
function (success, result) {
if (success) {
var center = result.routes[0].bounds.getCenter();
$(‘#map_canvas’).gmap(‘option’, ‘center’, center);
$($(‘#map_canvas’).gmap(‘getMap’)).triggerEvent(‘resize’);
} else {
alert(‘Unable to get route’);
}
});
// END: Tracking location with test lat/long coordinates
}
});
return false;
});
The event handler bound to ‘click’ on the refresh button (see the footer on page with id=”page-map” in index.html) creates the fullscreen map and directions panel (see the page id=”page-dir” in index.html).

The fullscreen map is created using the div id and plugin api: $(‘#map_canvas’).gmap(… This call creates the new map with one option, a callback. The callback function is called after the new google map is created, initialized and any option values applied (no other option data provided in this example).

The callback consists of one line besides the position-toggling code: another call to $(‘#map_canvas’).gmap.
In this second use of the plugin api, the method ‘displayDirections’ is the first parameter. This indicates a request to google maps to calculate the route between the two locations provided in the following options object, which is google’s DirectionsRequest (origin and destination). The third value set in the DirectionsRequest, travelMode, tells google maps to provide driving (vs. bicycling or walking) directions.

The next parameter, google’s DirectionsRendererOptions, uses the DOM element for the panel div, where the text directions will go. See <div id=”dir_panel”></div> in the page with id=”page-dir”  in index.html.

There many cases where the callback function provided in the gmap() creation call will be another call to gmap() with a method. In this example, it works well because there is no need to display the map before the route is found and rendered (the function displayDirections).

In order to simulate the user changing position relative to the destination, the test version of the javascript uses a toggle value (toggleval) to fake a different position with each refresh (origin toggles between Gothenburg and Motala). The block indicated by START and END can be replaced by identical code that uses PhoneGap’s geolocation to get current position (see step 7 below) instead of faking it.

6. Add event handlers and a fading hint box to directions page

jQuery Mobile’s pagecreate event is used to create the map the first time the page is navigated to.

The default behavior of the directions list provided by google maps works the same with the plugin and on mobile devices. Tapping on a direction will zoom in on the associated map to show details of that instruction. Unlike desktop, the map is on another page due to size. When the user taps on an instruction, the zoomed view will automatically appear on the map page. The tap (or click) event handler changes back to the map page to show the zoomed view.

Add the following code to the end mapapp.js.

// Map page
$(‘#page-map’).live(“pagecreate”, function() {
$(‘.refresh’).trigger(‘click’);
});

// Go to map page to see instruction detail (zoom) on map page
$(‘#dir_panel’).live(“click”, function() {
$.mobile.changePage(‘#page-map’, ‘slide’);
});

// Briefly show hint on using instruction tap/zoom
$(‘#page-dir’).live(“pageshow”, function() {
$(“<div class=’ui-loader ui-overlay-shadow ui-body-e ui-corner-all’><h1>”
+ “Tap any instruction” + “<br>” + “to see details on map” +”</h1></div>”)
.css({ “display”: “block”, “opacity”: 0.9, “top”: $(window).scrollTop() + 100 })
.appendTo( $.mobile.pageContainer )
.delay( 1400 )
.fadeOut( 700, function(){
$(this).remove();
});
});
A fading hint window is displayed to remind the user of this functionality whenever the directions page is shown. The images below show the fullscreen map and directions page.

The screen shots below show a detailed direction (tap on any instruction in directions list to zoom in on it) and a satellite view of the route after refreshing (toggling to other origin location, tap Satellite on map).
7. Option: Add PhoneGap’s Geolocation to find Route Dynamically

To use geolocation to dynamically find the route, make the following two changes.

Modify the first line of mapapp.js where the destination location is specified (mapdata). Find a location on your continent so the driving directions will be clear. A convenient tool to find latitude and longitude anywhere on the planet is Get Lat Lon by Simon Willison.

var mapdata = { destination: new google.maps.LatLng(59.3327881, 18.064488100000062) };

Add the following code to mapapp.js immediately before the existing block denoted by START and END comments.  Remove or comment out the existing code (the one using static locations in Sweden). For clarity this block is also denoted by START and END.

// START: Tracking location with device geolocation
if ( navigator.geolocation ) {
navigator.geolocation.getCurrentPosition (
function(position) {
$(‘#map_canvas’).gmap(‘displayDirections’,
{ ‘origin’ : new google.maps.LatLng(position.coords.latitude,
position.coords.longitude),
‘destination’ : mapdata.destination, ‘travelMode’ :
google.maps.DirectionsTravelMode.DRIVING},
{ ‘panel’ : document.getElementById(‘dir_panel’)},
function (success, result) {
if (success) {
var center = result.routes[0].bounds.getCenter();
$(‘#map_canvas’).gmap(‘option’, ‘center’, center);
$($(‘#map_canvas’).gmap(‘getMap’)).triggerEvent(‘resize’);
} else {
alert(‘Unable to get route’);
}
}
);
},
function(){
alert(‘Unable to get location’);
$.mobile.changePage(‘#page-home’, ‘slide’);
});
}
// END: Tracking location with device geolocation
Note: From the PhoneGap Documentation on geolocation: The Android 2.x simulators will not return a geolocation result unless the enableHighAccuracy option is set to true.

8. Challenge: Add more features using jQuery and jQuery Google Maps plugin

8.1 Add radio buttons on the home page to let the user select driving, biking or walking travel mode.

8.2 Add a control on the main map to toggle a traffic layer.

8.3 Add multiple markers/locations (i.e. business with multiple locations) and way for user the select the location they want to visit.