Posts Tagged ‘google maps’

Displaying GPS position in FlashLite using Google Static Maps and KuneriLite

Thursday, June 12th, 2008

Today’s tutorial is about using Google Maps static images, and GPS data, to display maps in a FlashLite application using KuneriLite.

FlashLite KuneriLite Google Maps application screenshot

Prerequisites

Get your own Google Maps API key

To use Google Maps services, you should have a Google Maps API key. If you do not have one, you can go here:

http://code.google.com/apis/maps/signup.html

and signup for your API key.

Download and install KuneriLite

KuneriLite is a tookit that extends FlashLite capabilites allowing applications to access native Symbian functionalities, like file writing, or reading GPS data.

To proceed in this tutorial, you must download and install KuneriLite: KuneriLite download page.

Create FlashLite application

Create your FlashLite movie

In this example, we’ll use FlashLite 2.1, but porting it to other (older or newer) FlashLite versions will be quite straightforward. So, after you’ve created an empty FlashLite movie, follow this simple steps:

  • Create a Button by going to Insert -> New Symbol…
  • enter GpsButton as name
  • check the Export for ActionScript and Export in first frame checkboxes

GpsButton properties

  • Now, design your Button as you prefer, for example placing a big “Find me!” label on it
  • After you’ve finished designing your Button, place it on movie root, in the lower part of the stage, as in the attached screenshot, and give it startButton as Instance Name

Place GpsButton on stage

Enter ActionScript code

On movie root, create a new layer called Actions, and open its ActionScript editor. We’ll start defining some properties:

// Enter your api key here
var apiKey = 'API_KEY';
 
//If you're using non-commercial version of KuneriLite, you'll not need to change this
var kuneriPath = 'http://127.0.0.1:1001/Basic/';

Now, we’ll define some useful functions that we’ll use in our code:

//We'll call this function when some KuneriLite related errors occur
function kuneriError(error:String)
{
	trace("KuneriLite error: " + error);
}
 
//This function will do all calls to KuneriLite servers
//and call the given handler passing response values as argument
function kuneriLoad(url, handler)
{
	var loader:LoadVars = new LoadVars();
 
	loader.onLoad = function()
	{
		handler(this);
	}
	trace("LOADING: " + url);
 
	loader.load(url);
}

Now, let’s code the Button-related logic. When the user presses the startButton we want to:

  • start the GPS
  • retrieve the current GPS position
  • display a map centered in the retrieved GPS position

To get full infos about about KuneriLite GPS plugin, you can check the related Wiki page: http://wiki.kunerilite.net/index.php?title=GPS_plugin

We begin starting the GPS on gpsButton press, using the start klCommand:

startButton.onPress = function()
{
	kuneriLoad(kuneriPath + 'GPS?klCommand=start', gpsStarted);
}
function gpsStarted(res:LoadVars)
{
	if(res.klError == 0 || res.klError == -11)
	{
		trace("GPS started");
 
		kuneriLoad(kuneriPath + 'GPS?klCommand=read', gpsDataRead);
	}
	else
	{
		kuneriError("Error starting GPS!");
	}
}

The gpsStarted() handler will:

  • check if there is no error (klError = 0) or if GPS is already started (klError = -11). For full errors list associated with GPS plugin, check KuneriLite Wiki page: http://wiki.kunerilite.net/index.php?title=GPS_plugin
  • if there’s an error starting the GPS, call our kuneriError() function defined above
  • if GPS is correctly started, it will make a second call to KuneriLite, this time to retrieve current GPS position (klCommand=read)

This second call to KuneriLite will call gpsDataRead() handler, defined below:

function gpsDataRead(res:LoadVars)
{
	if(res.klError == 0)
	{
		if(res.klPosLatitude != undefined)
		{
			var lat = res.klPosLatitude;
			var lng = res.klPosLongitude;
 
			trace("POSITION: " + lat + ", " + lng);
 
			loadMap(lat, lng);
		}
		else
		{
			kuneriLoad(kuneriPath + 'GPS?klCommand=read', gpsDataRead);
		}
	else
	{
		kuneriError("Error retrieving GPS position!");
	}
}

This handler, as above, will check if there is any error raised by KuneriLite and, if not, will check if latitude and longitude coordinates are available, by checking response klPosLatitude and klPosLongitude property values. If they’re not available, a new call to read klCommand is done, otherwise the following loadMap() function is called.

function loadMap(lat:Number, lng:Number)
{
	var mapClip:MovieClip = _root.createEmptyMovieClip('mapClip', _root.getNextHighestDepth());
 
	mapClip._x = 0;
	mapClip._y = 0;
 
	var mapWidth = 240;
	var mapHeight = 280;
 
	var loader:MovieClipLoader = new MovieClipLoader();
 
	var mapUrl:String = 'http://maps.google.com/staticmap?center=' +
		lat + ',' + lng + '&format=jpg&zoom=8&size=' +
		mapWidth + 'x' + mapHeight + '&key=' + apiKey;
 
	loader.loadClip(mapUrl, mapClip);
}

The above function:

  • attaches a new empty movie clip to movie root
  • places it to coordinates (0,0)
  • use a MovieClipLoader to load a 240×280 map image, in jpeg format, in the empty clip

Done that, you can actually test your FlashLite movie

Test your FlashLite application

Test on PC

To test your application without deploying on real device, you must follow these simple steps:

  • Start KuneriLite emulator with default settings (port: 1001, key: Basic)
  • Start your FlashLite movie
  • Press Find Me! and wait for your image to be loaded (of course, being an emulator, the GPS position will be not real :))

For more infos about KuneriLite Emulator, you can go here: KuneriLite Emulator Wiki page

Test on real device

To test your app on real device, you must package your SIS application using KuneriLite Wizard, following these steps:

KuneriLite Emulator screenshot

  • Export your FlashLite movie
  • Create a new KuneriLite project
  • Enter application name and other data, checking GPS from the available plugins
  • Check “Use external player” option if you developed for a development player (2.x or 3.x) and would like to launch the application using one of those players
  • It is also recommended to always check “Use stub” option
  • Select the exported SWF as project Main SWF

Note: to use GPS you should sign your application, specifying certificate, key and password in KuneriLite Wizard interface. Otherwise, your application will not be able to access GPS functionalities.

For more infos about KuneriLite Wizard, you can go here: KuneriLite Wizard Beginner’s Guide

Source code and resources

Google Maps mobile tutorial is Wiki article of the Month!

Wednesday, June 11th, 2008

I’m really honored that another article, published on Forum Nokia Wiki, has been selected as Article of the Month!

Google Maps article of the month

As the previous one, this also is related to Google Maps usage in mobile applications, and you can read it here: How to use Google Maps data in mobile applications.

As its name says, It’s an introductory article on how to use Google Maps services, in particular the geocoding and static maps ones, from a mobile application, where standard Google Maps API code is not suitable (since it is thought for web based and Ajax’d apps). Its content does not focus on any particular programming language, but gives base guidelines to use those services using REST.

So… any kind of feedbacks is welcome! :)

J2ME Google Maps API is article of the week on Forum Nokia!

Monday, June 9th, 2008

I’m really happy to announce that my J2ME Google Maps API article on Forum Nokia Wiki has been selected as Article of the Week! :)

J2ME Google Maps API Article of the Week

And, to celebrate this event, I’ve added a brand new feature to my article that will allow you to:

  • create larger tiled maps
  • support map scrolling

How does it work?

You start instantiating a GoogleMaps object as usual:

GoogleMaps gMap = new GoogleMaps("API_KEY");

Then you get your map, for example geocoding a given address:

double[] coords = gMap.geocodeAddress("Leicester square, London");
 
Image mapImage = gMap.retrieveStaticImage(
	150, 150,
	coords[0], coords[1],
	12, "png"
);

Then, let’s say you want to scroll your map 100 pixels up, what you’ll do is:

double[] newCoords = gMap.adjust(
	coords[0], coords[1],
	0, -100, 12
);
 
Image newMapImage = gMap.retrieveStaticImage(
	150, 150,
	newCoords[0], newCoords[1],
	12, "png"
);

As you’ve seen, the adjust method takes these arguments:

  • the current latitude and longitude
  • the deltaX and deltaY, in pixels
  • the current zoom level

and returns the new map center latitude and longitude coordinates.

You can check the full updated source code on Forum Nokia Wiki article: J2ME Google Maps API, and a full-featured example, with the scrolling feature, on the emulator page: J2ME Google Maps API in action.

How to use Google Maps data within your mobile application

Wednesday, May 14th, 2008

Note: You can find this article also on Forum Nokia Wiki: How to use Google Maps data in mobile applications

Today we’ll see how to use Google Maps data within a mobile application.
Google Maps offers REST services that allows accessing its data with simple HTTP requests, so we can easily integrate them within our mobile apps.

Signup for a Google Maps API key

First thing you must do is to signup on this page:
http://code.google.com/apis/maps/signup.html
Once done, you’ll get a key (a simple String) you’ll use for all your query to Google Maps services

Static maps

Standard Google Maps code is suited for web applications, since it includes alot of Ajax functionalities, that are not really useful if you’re building a mobile application. So, the solution is to use static maps service, that will allow us to retrieve single images, easily usable within our apps.

Static maps service supports different image formats (png32, gif, jpg) and customizable image size, so that we can get perfect images for all our needs. As an example, suppose we want to retrieve the location at:

  • latitude: 41.867878
  • longitude: 12.471516

We can simply retrieve this URL with an HTTP GET request:

http://maps.google.com/staticmap?center=41.867878,12.471516&
format=png32&zoom=8&size=240x320&key=<API_KEY>

This way, we’ll get a PNG32 image, with a width of 240 pixels, and a height of 320, centered at point (41.867878,12.471516), and with a zoom level of 8 (zoom can go from 0 to a maximum level of 19).

Google Maps static image sample

Geocode an address

From Google Maps docs:
Geocoding is the process of converting addresses (like “1600 Amphitheatre Parkway, Mountain View, CA”) into geographic coordinates (like latitude 37.423021 and longitude -122.083739)

So, let’s assume we want to build an application that displays the address typed by our user. We should firstly geocode its address to geographics coordinates.
To do this, Google Maps offer another REST service easily accessible with simple HTTP requests.

Let’s say you want to geocode this address “Leicester Square, London”, then you’ll request this URL:

http://maps.google.com/maps/geo?q=Leicester%20Square,%20London
&output=csv&key=<API_KEY>

and you’ll get this output:

200,6,51.510605,-0.130728

Where:

  • the first number is a code, that in this case (200) means that geocoding has been successfull (for a full list of status codes you can see here: [1])
  • the second number gives a measure of geocoding accuracy (from 0 to 9 - maximum accuracy)
  • 3rd and 4th numbers represent latitude and longitude of the geocoded address, so these are the coordinate we’ll use to retrieve the map through the static map service we’ve seen before

As you can see, there is an ‘output’ parameter within the geocode request, and this means that we can choose the output format we prefer for our needs. Supported formats are:

  • xml
  • kml (same as xml, but with different Content-Type)
  • json (not really useful for mobile apps)
  • csv (comma separated values)

Proxy server, usage limits

Since your Google Maps API key is bound to a specific URL, to access map services you should setup a proxy server that will receive HTTP requests from your mobile application and forward them to Google Maps REST URLs, giving back Google responses to mobile clients.

Also, be aware that there is a limit to the number of requests (both for static maps and geocode service) you can do each day. For personal uses they’re more than enough, anyway consider this point if you plan to develop commercial services.

Google Maps J2ME API and sample application

Now, you want code right? :) Here it is:

Google Maps sample application screenshot