Posts Tagged ‘OpenSource’

MyOpenPos: Open Source positionnig

Tuesday, July 8th, 2008

In the first part, we’ve introduced CellID, and OpenCellID – the OpenSource database of CellID - and we have created a small program to retrieve position from CellID information.

This time, we will go on step further and display a map, based on open source data OpenStreet map, on your mobile phone, based on your location.

This will be close to the experience of Google Map “MyLocation” on mobile, and will run on top of JavaME.

So to achieve this, we will use J2memap component. J2memap is a library that we have created to develop our flagship product, a mobile tourist guide. But the purpose of this library is to easily create mobile application based on a Map. This library is free for non commercial use.
This component can display map based on any tile provider, like Google, MSN or others, but also OpenStreetMap. On top of this, you can add extra layers as bitmap or KML, GeoRSS, GPX and much more.
A complete description of the feature is available at http://j2memap.8motions.com .

The HelloMap program!

So how to use it? It’s very simple, you can use MapDisplay. The simplest J2memap program is like this one:

import com.eightmotions.map.MapDisplay; import com.eightmotions.util.UtilMidp; import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class HelloMap extends MIDlet { public void startApp() { UtilMidp.checkMIDP(this); //Initialise the utility library... Display.getDisplay(this).setCurrent((new MapDisplay()).getCanvas()); } public void pauseApp() {} public void destroyApp(boolean unconditional) {} }

You see, just create a MapDisplay and display the related Canvas. Now, you can play with a map, move it, etc…

The result looks like good already:

Using OpenStreeMap as a Map provider

So, we need now to do two things: integrate OpenStreetMap, and use OpenCellID feature.
The OpenStreeMap integration is quite easy: you can implement or replace layers, by implementing the MapOverlay interface.
But even better, there is the “GenericOverlay” classes, which take care of most of the hard complex, and just need an URL, and a few settings:

MapOverlay openStreeMap=GenericOverlay(“OpenStreeMap”,”http://tile.openstreetmap.org/!z!/!x!/!y!.png");

The URL contains some special token, the ones between ‘!’ like ‘!x!’,’!y!’, and ‘!z!’.
These are dynamically replaced by the corresponding value at run time, they are related to lon, lat and zoom level.
I will not go into detail of these values, they are beyond the scope of this article, but you should know that you
have others values, like !minLon!,!minLat!, etc…. In other words, this could be very easily used to connect to a WMS server….
Then we just tell the engine to display it:

myMap.setMapProvider(0,openStreeMap);

Retreiving results of OpenCellID

At this level, we will already a map application where we can zoom in /out connected to OpenStreeMap. We just reuse the code of our last week sample, and add the following at the end of the treatment of the OpenCellID result:

.... int pos=res.indexOf(','); String latStr=res.substring(0,pos); int pos2=res.indexOf(',',pos+1); String lonStr=res.substring(pos+1,pos2); myMap.setInfoOnScreen(latStr+" "+lonStr); float lat=Float.parseFloat(latStr); float lon=Float.parseFloat(lonStr); // If we are in a lower zoom mode, go into an higher mod if(myMap.getZoom()<10)myMap.setZoom(14); // If the 'current location' is not yet created, do it, and add it in the current track if(lastLoc==null){ lastLoc=new MyLoc(); t.addLoc(lastLoc); } lastLoc.setLonLat(lon,lat); myMap.goTo(lastLoc);

Adding a custom Marker: using Marker

What is this MyLoc element? Using the libray, you can add element on top of the map, like pins, markers, etc… You can use picture to do your own marer, but in this example, we will create our own custom marker, an empty circle
To do this, we just extends the default Marker, add the size field/

Note: at this stage, the range value returned by the API is wrong, so we won’t use it and we will set a predefined size for your cell range….

class MyLoc extends Marker{ public int range=1000; public MyLoc(){ super(); } public void paint(Graphics g,int inpx,int inpy,int offx,int offy,int w,int h,int zoom){ int x=offx+w/2+(px-inpx)/(1<<zoom); int y=offy+h/2+(py-inpy)/(1<<zoom); g.setColor(0x8080A0); g.fillArc(x-6,y-6,12,12,0,360); g.setColor(0x0000C0); g.drawArc(x-50,y-50,100,100,0,360); } }

Conclusion

The result is the following: when you press the “LocateMe” button on your phone, a request will be sent to the OpenCellID server, trying to see if we find a correspondence between this CellID and a location. If this is found, then, we move the map to this location.

A few shortcuts are available:

1 to zoom in, 3 to zoom out, 5 to change of map provider

Important: as discussed in the first article, only latest SonyEricsson provides access to CellID on JavaME. On others phone, if you attempt to use this feature, the program will warn you through a “this phone does not support CellID”.

The complete source code is available here.The compiled program is available here, with jad and jar.

If you have any questions, remarks, comment, feel free to ask: t.landspurg@8motions.com

Zemanta Pixie