http://www.developer.com/java/j2me/article.php/3825706/Using-Location-Enabled-MIDlets-for-Mobile-Navigation.htm
Location information has become fairly easy to access nowadays, even on mobile devices. The widespread availability of GPS chipsets such as the SiRF chipsets, which are accurate to within a few meters, as well as the significantly lower costs of these products, have contributed to the accessibility. The Location API for J2ME (JSR 179) even makes it very easy for developers to integrate location information into mobile applications. This article illustrates how to combine JSR 179 and Scalable Vector Graphics (SVG) to provide navigation for a GPS-enabled mobile device. The application will employ the Scalable 2D Vector Graphics API for J2ME (JSR 226) and a MIDlet. As an example, the article provides and refers to a sample NetBeans project for a college "campus navigation" application. In mobile-based location methods, you have GPS (Global Positioning System). GPS is potentially the most accurate method, but it has a couple of drawbacks. First, it consumes a lot of battery power while in use. Second, its performance suffers in canyon environments such as cities, where satellite visibility is intermittent, tall buildings block the GPS signals, and satellite signals are too limited to estimate the position of the user. The following are the two types of mobile-based location methods for GPS: Most modern mobile devices that have a mobile GPS chipset and use KVM will support JSR 179. Table 1 lists the main JSR 179 Location API classes. If you use a Nokia mobile phone, the Nokia PC Suite allows you to deploy the sample MIDlet from the NetBeans environment directly on the phone through a USB cable. Use a similar methodology for mobile phones from other vendors. The following are screenshots of the running application on an emulator. The SVG file first defines the DTD and the SVG Tiny version used by the mobile device (SVG Tiny 1.2 in this case). The SVG size and the image size are then defined, and the image definition is linked to the URL of the image on the web server. Finally, lines are defined vertically and horizontally to form a grid for ease of location (see Listing 4, which defines the image and its location, as well as the grid for the mobile display of the campus). The declaration of the class called LocPos in the sample NetBeans project for this article is: Table 2 provides the various classes and interfaces available in JSR 226: Scalable 2D Vector Graphics API for J2ME, which are used to implement SVG functionality. In the sample NetBeans project for this article, the Canvas used for displaying the SVGImage of the campus layout is a class derived from Canvas called GameCanvas. This is used because the Game Keys can be utilized for positioning the image. The zoom in and zoom out functions in the image displayed in the GameCanvas are achieved with the JSR 226 SVG classes shown in Table 2. The following gets the root SVG element in the SVG document tree into myEl. From the getBBox() function (BBox stands for bounding Box), you can get the height and width of the SVG root object. This scaling is carried out with respect to the top-left corner, whose coordinates are (0,0). In order to zoom in and out with respect to the center of the display, a translation has to be applied after scaling (as the code will show shortly). To achieve this translation, the SVGPoint p1 obtained from the getCurrentTranslate() method shown above is used to get the X and Y coordinates of the current translated position, as shown below. In the startapp() method of the MIDlet in this example, you instantiate a TextBox and pass it when creating a new instance of the Location object, LocPos. This TextBox is used to display the current latitude, longitude, and time of the mobile device. Then the back command is added to the TextBox. A new thread is started with the LocPos object in a try/catch construct. This thread will constantly update the TextBox with the current latitude and longitude, as well as the time stamp. Next, the main MIDlet menu items are generated by getList(). The main menu has three items: The getList() method returns a list of these three items. In the startApp() method, disp.setCurrent(getList()) will display the list of three items by making the Displayable List object the current display on the screen. If GetLocation is invoked, the listAction() method will set the current display to the TextBox and display the location and time with date. If the user selects See Campus, the corresponding listAction() code will be invoked. This code will start a new SVGStatic Canvas thread, which will get its position updated from the LocPos thread, and implement the zoom and translation features in the campus map used. If the user exits from the See Campus function, then the SVGStatic Canvas thread is made null before going back to the main menu of the three items (Get Location, See Campus, and Exit). The pauseApp() and destroyapp() methods are left blank, but you can incorporate any functionality as needed. Listing 3 (SVGMidlet.java) provides insight into the implementation of the main MIDlet for invoking and controlling the location monitoring as well as the campus navigation operations. One way of displaying the campus is to correspond the top of the mobile screen to north, the bottom to south, the right to east, and the left to west. Another way is to display west on top, east below, north on the right, and south on the left, with the top-left corner corresponding to the X and Y coordinates (0,0). For example, consider a device screen that is 240 pixels wide and 340 pixels tall. Having north correspond to the top of the screen would mean that when the latitude is at its maximum (say, for example, maxlat is 82.245 degrees), the position will be on the line at top of the screen and ycoord = 0. So as the user moves south toward lower latitudes, the position will shift downwards and ycoord will increase up to a maximum of 320. Similarly, as the user moves eastward from left to right and the longitude increases, the x coordinate will also increase from 0 to 240. The second approach (keeping west on top, east on bottom, north on the right, and south on the left) is very simple. As the user moves down (eastward), the longitude increases and the y coordinate also increases. As the user moves from left to right (northward), the latitude increases and so does the x coordinate. Remember that in the Southern Hemisphere as the user moves northward, the latitude will decrease. See the two diagrams below.
Using Location-Enabled MIDlets for Mobile Navigation
June 17, 2009
Author's Note: The content of the article is the view of the author and not that of Wipro Technologies.
Determining the Device Location
You can determine the location of a mobile device in several ways. Mobile-location methods can be based either on a network or a mobile device. In the network-based location method, you have the following options: Classes Functionality LocationProvider Used for the selection of the location provider Criteria Represents a source of the location information, starting point of location request Location Represents the standard set of basic location information. This includes the time-stamped coordinates, accuracy, speed, course, etc. Coordinates Represents coordinates as latitude-longitude-altitude values. LocationListener Listener that receives update events associated with a particular LocationProvider ProximityListener Receives updates based on terminal crossing into a defined radius around a coordinate. Landmark The Landmark class represents a landmark, such as a known location with a name (such as a monument) LandmarkStore The LandmarkStore class provides methods to store, delete and retrieve landmarks from a persistent landmark store. Table 1. Main JSR 179 Location API Classes The NetBeans Project
The NetBeans project LocationEnabMidletProj.zip is provided here for demonstration. After unzipping the project, you can open it in NetBeans (The examples discussed here are from NetBeans IDE 6.5.1). You can test it on the Java Wireless Tool Kit, which comes as part of the NetBeans Mobility Pack.
Click here for larger image
Figure 1. Map Screen: This capture of the emulator shows the running MIDlet displaying the campus of Brock University.
Click here for larger image
Figure 2. Map Screen Menu: This capture shows the screen menu for the campus navigation with zoom in and zoom out facility.
Click here for larger image
Figure 3. Zoomed Map Screen: This capture shows the zoomed campus.The Sample SVG File
A sample SVG file, which is used by the MIDlet, invokes the Campus JPEG file from a web server. For testing with the Java Wireless Tool Kit emulator, the web server can be hosted on the development machine that runs NetBeans. Implementing the Location API
To determine location by finding the current latitude and longitude, you have to declare a class that is runnable and also a listener. Runnable is required because you want the instantiated class to be a thread that is constantly running, so it can get updates of the user's current position and send them to the application. The application will use the updates to reposition the coordinates on the screen map. The listener functionality is added because whenever there is a location change, the listener will automatically be notified. public class LocPosition implements Runnable, LocationListener {You first need a LocationProvider object and a Location object to store the latitude and longitude. After declaring these objects, you have to establish the criteria for getting the location from the LocationProvider (through the satellites). The following code snippet does this: Location loc;LocationProvider provider= nulltry { Criteria crit = new Criteria(); crit.setCostAllowed(true); //default value crit.setPreferredPowerConsumption(Criteria.NO_REQUIREMENT); /*Filling up default values required for Criteria before getting instance of Location Provider */ provider = LocationProvider.getInstance(crit); } catch (LocationException ex) { ex.printStackTrace(); }Then you initialize the LocationListener for the provider object obtained: provider.setLocationListener(this,-1,-1,-1); /*setting up the location listener with default values so that locationUpdated() function
Once the LocationProvider is initialized, you also need to implement the locationUpdated method, which will be invoked by the listener process every time a change in location occurs. Because this method is triggered only when a location change occurs, it gets the coordinates from the Location object and locPos. It also gets the time stamp of the reading, as shown in this code snippet:
is called when there is a change in location */public void locationUpdated(LocationProvider provider, Location locPos) { /* Updating of latitude, longitude, and time when The full listing of Location.java is available in Listing 1. Location.java implements all the features for initializing the location provider and getting the updates of the new position in the listener process when changes to location occur.
locationUpdated() is called on change of location */ coordinates = locPos.getQualifiedCoordinates(); sb.delete(0,sb.length()); sb.append(new Date(locPos.getTimestamp()).toString()); latitude = coordinates.getLatitude(); longitude = coordinates.getLongitude(); }Implementing the SVG API
SVG is an XML grammar for rich, dynamic 2D graphics. It boasts the following attributes: Class or Interface Description javax.microedition.m2g Scalable Graphics Fundamental class for 2D rendering SVGAnimator Class handles automatic rendering of updates and animations in an SVGImage to a target user interface component SVGEventListener Interface used to forward platform-specific events to an application SVGImage Class represents an image conforming to W3C SVG Tiny 1.1 (1.2) Profile External Resource Handler Interface is used to load synchronously any external resources needed for loading SVG content org.w3c.dom.svg SVGAnimationElement Interface represents an animation element and includes methods to control timing of animations SVGElement Interface represents an SVG element in the document tree SVGLocatableElement Interface represents a drawable SVG element (typically a shape, image, or text) SVGMAtrix Interface represents an SVG matrix data type identified by an affine transformation equivalent to a linear transformation followed by a translation SVGPath Interface represents a SVG path data type used to define path geometry SVGPoint Interface represents a SVG point data type identified by its X and Y components SVGRect Interface represents a SVG rectangle data type consisting of mimimum X, minimum Y, width and height values SVGRGBColor Interface represents a SVG RGB color data type composed of red, green, and blue componets SVGSVGElement Interface represents an element in SVG document tree (Whereas SVGElement represents a SVG element in the document tree.) Table 2. Classes and Interfaces in JSR 226 SVGSVGElement myEl = (SVGSVGElement)(
You can get the current scaling factor by using the getCurrentScale() method of the root SVGElement. Similarly, you can get the current translate position using the getCurrentTranslate() method.
svgImage.getDocument().getDocumentElement());SVGRect myRect = myEl.getBBox();float fa = myEl.getCurrentScale();SVGPoint p1= myEl.getCurrentTranslate();
To zoom in, you can multiply the current scale by a factor. This example uses 1.2. The setCurrentScale() method is used for setting the scale. For zoom out, you multiply current scale by a factor of 1/1.2. float xf = p1.getX();float yf = p1.getY();
Then the setX() and setY() methods are used to change the translation coordinates, where delta_x and delta_y are the X and Y coordinates by which the current position must be translated. p1.setX(xf + delta_x);p1.setY(yf + deltay);
Listing 2 shows the code for the complete functionality in SVGStaticCanvas.java. The code is for the Canvas UI, the display of the campus map on the screen, and the zoom in, zoom out, and translation functions. Implementing the MIDlet
Every MIDlet must have a startApp() method to initialize the MIDlet application, a pauseApp() method to pause it, and a destroyApp() method to terminate the MIDlet. The class SVGMidlet extends the MIDlet class and implements a CommandListener interface. Running the MIDlet
First, it is important to find out the maximum and minimum longitude and the maximum and minimum latitude of the campus where the mobile location-enabled MIDlet will be used. These values are stored in the code, as indicated in Listing 2 (SVGStaticCanvas.java), in the variables minlong, maxlong, minlat, and maxlat, respectively.
Click here for larger image
Figure 4. Mobile Screen Orientation for West on Top and East Below
Click here for larger image
Figure 5. Mobile Screen Orientation for North on Top and South Below About the Author
Jayasurya Venugopalan has 29 years of industry and academic experience. He works as a Senior Consultant at Wipro Technologies, Bangalore specializing in networking, network management, and NGOSS.