IntegrateGoogleMapsWithCurrentLocation
From WebOS101
Introduction
Are you looking for a Map widget in Mojo? Well, there isn't any yet. There is one in Ares, but if you're more of a vi-guy/gal and uncomfortable with a web IDE, you'll need to roll your own map. Don't dispair though, others have pulled their hair for you, so you can keep your long hippie hair...
In this tutorial, you will be adding a vanilla Google Maps widget into your app. That is, you will be using Google Maps API v3 for Javascript. Just like you would when embedding it in your cool homepage, only on WebOS and with some suger on top!
If you need help, don't hesitate to contact me: webos {'@'} jelica.se or twitter.com/b0bben
Nuff' of the witty talk, let's get down to business!
Teh codes!
You can pretty much follow the regular Google Maps API tutorials on their page to get a map into your webos app. What we're gonna do here is sprinkle that with some CSS3 magic to give it a nice blue pulsating dot that shows current location of the phone thru Location Services.
First things first, you'll need to include Googles Maps javascript into your project. In your index.html file, add this among the other script tags:
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>
Make sure the sensor value is there. It's very important, or so says Google.
Next, add a div-element to your scenes view:
<div id="map_canvas" style="width: 320px; height: 480px;"></div>
Above html code will create a div that takes up the whole available space in your scene view in portrait mode. Adjust the width and height CSS style to suit your app better, if needed.
That's it for the HTML, now let's get busy with the Javascript. In your scene assistant, start by adding these 2 variables which we'll need later.
function MyAwesomeAppAssistant() {
/* this is the creator function for your scene assistant object. It will be passed all the
additional parameters (after the scene name) that were passed to pushScene. The reference
to the scene controller (this.controller) has not be established yet, so any initialization
that needs the scene controller should be done in the setup function below. */
this.myMarker = false;
this.map;
}
Now, in your scene assistant, add the following code in your setup function:
MyAwesomeAppAssistant.prototype.setup = function() {
/* map inits */
var myOptions = {
zoom: 8,
navigationControl: true,
scaleControl: true,
mapTypeControl: false,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
//our map instance
this.map = new google.maps.Map(this.controller.get('map_canvas'), myOptions);
};
Above code will create a map using Googles javascript code and place it into your div that you created earlier. This will actually give you a working Google Maps map in your app already! You can zoom by double-tapping, move the map around etc.
Let us continue on our journey for awesome maps widget, shall we?
Now we want to tell the phone to start tracking our location using the Location Services.
this.controller.serviceRequest('palm://com.palm.location', {
method:"startTracking",
parameters:{
subscribe: true
},
onSuccess:this.displayLocation.bind(this),
onFailure:this.locationFailure.bind(this)
}
);
This will instruct the phone to provide us with a latitude and longitude for our current location and keep updating us on changes. That's what "startTracking" is. There is another value called "getPosition" which can be used for one-time purposes, when you don't need the constant updates.
As you can see, the onSuccess callback is set to the method "displayLocation" in our code, which will be called each time there is a position update on our phone. Here is the code:
MyAwesomeAppAssistant.prototype.displayLocation = function(position){
var myLatLng = new google.maps.LatLng(position.latitude, position.longitude);
// build entire marker first time thru
if (! this.myMarker) {
// define the 'you are here' marker image
var image = new google.maps.MarkerImage('images/blue_dot_circle.png',
new google.maps.Size(38, 38), // size
new google.maps.Point(0, 0), // origin
new google.maps.Point(19, 19) // anchor
);
// then create the new marker
this.myMarker = new google.maps.Marker({
position: myLatLng,
map: this.map,
icon: image,
flat: true,
title: 'I might be here'
});
// just change marker position on subsequent passes
} else {
this.myMarker.setPosition(myLatLng);
}
};
Now we're talking, right? Code above will plot out our current position, which we got from the phone, and use a special image for the marker. Remember, this method is called everytime our position changes.
Now for the sugar bit. Instead of a regular, boring red marker which is the default one in google maps, we'll make our marker blue and pulsating, just like on the iPhone (well, almost). And for that we'll use CSS3, that awesome new thing you hear everyone talk about.
Add the following to your styles.css file
/* pulse the 'I am here' location marker */
@-webkit-keyframes pulse {
0% {
opacity: 1.0;
-webkit-transform: scale(1.05);
}
40% {
opacity: 0.25;
-webkit-transform: scale(0.85);
}
100% {
opacity: 1.0;
-webkit-transform: scale(1.05);
}
}
#map_canvas div[style*="blue_dot_circle.png"]:not([title]) {
-webkit-animation-name: pulse;
-webkit-animation-duration: 2s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: ease-in-out;
}
See that? That's magic my friend, pure sexy magic. The blue dot circle image is available at Plebeosaur's page. That's were I found the pulsating first described. Go thank him/her. A lot.
So, test your app now, and marvel at the beautiful map you've got there.
Here is an example from our app Bensinjakt:
Further reading
Like always, check the Palm documentation for the Location Services
Read the Google Maps API documentation, and follow the easy tutorials there.
Also, go and thank the Plebeosaur guy who figured this pulsating thing out.


