Discusses a technique to record current geographic location from mobile and display in web pages (with Location History Browsing) Show
IntroductionLocation-based services (LBS) are becoming more and more popular nowadays. There are several mobile applications that detect user's current geographical location, provide related information about the location and also display location in Web. This article discusses how to develop a similar application (both mobile and web part) that will allow the user to save their location from mobile and display their current location in web pages with location history browsing in map. I will show a live demonstration where all these are working together! BackgroundLast year, I started to develop my personal website, one thing piqued my interest. I was thinking about how I can make my homepage different from others. I was fascinated by Google Maps for mobile and thought why not I develop a similar thing - a small application that will show my current location in my homepage. I started digging into this topic and it took me no time to find JSR 179 - J2ME Location-Based Services. I could use any of the available applications to show my location (e.g., Google Latitude), but I was interested to play with my GPS traces. I also have a mobile device with built-in GPS module (a common feature for modern Smartphone), so the platform is set for development :). Technologies UsedAlthough I will be using J2ME Wireless Toolkit 2.5.2, PHP, HTML, CSS, jQuery, MySQL (a little bit of everything :P) in this article, strong technical background on these is not required. You can use any combination of technologies to develop a similar application. A Quick TourLet's have a quick view on what we will be developing throughout this article. Following are the screenshots of the Mobile application: And here is the Web application: URLs for the web application: My Current Location and Browse my GPS traces history. Ok, enough screenshots. Now we start developing our app. First things first, let's start with the mobile application. Mobile Application: MapMeYes, I call it MapMe. MapMe will perform the following tasks:
Don't panic if your mobile does not have GPS unit. I will discuss how to detect location with a non GPS phone later in this article. Ok, let's start coding! I am using NetBeans IDE. Let's create a J2ME project in NetBeans and add a public static double[] getLocation(LocationProvider lp) throws Exception { double []arr = new double[3]; if(lp != null) { switch(lp.getState()) { case LocationProvider.AVAILABLE: Location l = lp.getLocation(-1); QualifiedCoordinates c = l.getQualifiedCoordinates(); if(c != null ) { double lat = c.getLatitude(); double lon = c.getLongitude(); double alt = c.getAltitude(); String latStr = Double.toString(lat).substring(0,7); String lonStr = Double.toString(lon).substring(0,7); lat = Double.parseDouble(latStr); lon = Double.parseDouble(lonStr); arr[0] = lat; arr[1] = lon; arr[2] = alt; } else { throw new Exception("Co ordinate is null!!"); } break; /* Other cases are handled here */ default: break; } } return arr; }3 class, call it public static double[] getLocation(LocationProvider lp) throws Exception { double []arr = new double[3]; if(lp != null) { switch(lp.getState()) { case LocationProvider.AVAILABLE: Location l = lp.getLocation(-1); QualifiedCoordinates c = l.getQualifiedCoordinates(); if(c != null ) { double lat = c.getLatitude(); double lon = c.getLongitude(); double alt = c.getAltitude(); String latStr = Double.toString(lat).substring(0,7); String lonStr = Double.toString(lon).substring(0,7); lat = Double.parseDouble(latStr); lon = Double.parseDouble(lonStr); arr[0] = lat; arr[1] = lon; arr[2] = alt; } else { throw new Exception("Co ordinate is null!!"); } break; /* Other cases are handled here */ default: break; } } return arr; }4. Let's add five public static double[] getLocation(LocationProvider lp) throws Exception { double []arr = new double[3]; if(lp != null) { switch(lp.getState()) { case LocationProvider.AVAILABLE: Location l = lp.getLocation(-1); QualifiedCoordinates c = l.getQualifiedCoordinates(); if(c != null ) { double lat = c.getLatitude(); double lon = c.getLongitude(); double alt = c.getAltitude(); String latStr = Double.toString(lat).substring(0,7); String lonStr = Double.toString(lon).substring(0,7); lat = Double.parseDouble(latStr); lon = Double.parseDouble(lonStr); arr[0] = lat; arr[1] = lon; arr[2] = alt; } else { throw new Exception("Co ordinate is null!!"); } break; /* Other cases are handled here */ default: break; } } return arr; }5s ("Locate Me" ,"Map Me", "Save Me", "About Me", "Start") in it to perform the operations. (I will not discuss J2ME related details here, i.e. what is public static double[] getLocation(LocationProvider lp) throws Exception { double []arr = new double[3]; if(lp != null) { switch(lp.getState()) { case LocationProvider.AVAILABLE: Location l = lp.getLocation(-1); QualifiedCoordinates c = l.getQualifiedCoordinates(); if(c != null ) { double lat = c.getLatitude(); double lon = c.getLongitude(); double alt = c.getAltitude(); String latStr = Double.toString(lat).substring(0,7); String lonStr = Double.toString(lon).substring(0,7); lat = Double.parseDouble(latStr); lon = Double.parseDouble(lonStr); arr[0] = lat; arr[1] = lon; arr[2] = alt; } else { throw new Exception("Co ordinate is null!!"); } break; /* Other cases are handled here */ default: break; } } return arr; }5, public static double[] getLocation(LocationProvider lp) throws Exception { double []arr = new double[3]; if(lp != null) { switch(lp.getState()) { case LocationProvider.AVAILABLE: Location l = lp.getLocation(-1); QualifiedCoordinates c = l.getQualifiedCoordinates(); if(c != null ) { double lat = c.getLatitude(); double lon = c.getLongitude(); double alt = c.getAltitude(); String latStr = Double.toString(lat).substring(0,7); String lonStr = Double.toString(lon).substring(0,7); lat = Double.parseDouble(latStr); lon = Double.parseDouble(lonStr); arr[0] = lat; arr[1] = lon; arr[2] = alt; } else { throw new Exception("Co ordinate is null!!"); } break; /* Other cases are handled here */ default: break; } } return arr; }3, etc.). In the public static double[] getLocation(LocationProvider lp) throws Exception { double []arr = new double[3]; if(lp != null) { switch(lp.getState()) { case LocationProvider.AVAILABLE: Location l = lp.getLocation(-1); QualifiedCoordinates c = l.getQualifiedCoordinates(); if(c != null ) { double lat = c.getLatitude(); double lon = c.getLongitude(); double alt = c.getAltitude(); String latStr = Double.toString(lat).substring(0,7); String lonStr = Double.toString(lon).substring(0,7); lat = Double.parseDouble(latStr); lon = Double.parseDouble(lonStr); arr[0] = lat; arr[1] = lon; arr[2] = alt; } else { throw new Exception("Co ordinate is null!!"); } break; /* Other cases are handled here */ default: break; } } return arr; }8 method, we initialize public static double[] getLocation(LocationProvider lp) throws Exception { double []arr = new double[3]; if(lp != null) { switch(lp.getState()) { case LocationProvider.AVAILABLE: Location l = lp.getLocation(-1); QualifiedCoordinates c = l.getQualifiedCoordinates(); if(c != null ) { double lat = c.getLatitude(); double lon = c.getLongitude(); double alt = c.getAltitude(); String latStr = Double.toString(lat).substring(0,7); String lonStr = Double.toString(lon).substring(0,7); lat = Double.parseDouble(latStr); lon = Double.parseDouble(lonStr); arr[0] = lat; arr[1] = lon; arr[2] = alt; } else { throw new Exception("Co ordinate is null!!"); } break; /* Other cases are handled here */ default: break; } } return arr; }9 based on specified public class MapViewer extends Canvas implements GoogleStaticMapHandler,CommandListener { /*Other fields here*/ private String apiKey = "Your-GoogleMap(API-v2)-apiKey" ; public MapViewer(MIDlet midlet, Displayable mainScreen, double lat, double lon) { this.lat = lat; this.lon = lon; this.mainScreen = mainScreen; this.midlet = midlet; this.addCommand(this.backCommand = new Command("Back", "Back to Search", Command.BACK, 0)); this.addCommand(this.zoomInCommand = new Command("Zoom in", Command.OK, 1)); this.addCommand(this.zoomOutCommand = new Command("Zoom out", Command.OK, 2)); this.setCommandListener(this); this.gMaps = new GoogleMaps(this.apiKey); map = gMaps.createMap(getWidth(), getHeight(), GoogleStaticMap.FORMAT_PNG); map.setHandler(this); map.setCenter(new GoogleMapsCoordinates(this.lat, this.lon)); GoogleMapsMarker redMarker = new GoogleMapsMarker(new GoogleMapsCoordinates(this.lat, this.lon)); redMarker.setColor(GoogleStaticMap.COLOR_RED); redMarker.setSize(GoogleMapsMarker.SIZE_MID); map.addMarker(redMarker); map.setZoom(15); map.update(); } protected void paint(Graphics g) { map.draw(g, 0, 0, Graphics.TOP | Graphics.LEFT); } /*Other codes i.e. going back to previous display stay here*/ }0. Java Criteria cr = new Criteria(); cr.setHorizontalAccuracy(Criteria.NO_REQUIREMENT); cr.setVerticalAccuracy(Criteria.NO_REQUIREMENT); cr.setCostAllowed(true); cr.setPreferredPowerConsumption(Criteria.POWER_USAGE_HIGH); this.locationProvider = LocationProvider.getInstance(cr); Now we start writing public class MapViewer extends Canvas implements GoogleStaticMapHandler,CommandListener { /*Other fields here*/ private String apiKey = "Your-GoogleMap(API-v2)-apiKey" ; public MapViewer(MIDlet midlet, Displayable mainScreen, double lat, double lon) { this.lat = lat; this.lon = lon; this.mainScreen = mainScreen; this.midlet = midlet; this.addCommand(this.backCommand = new Command("Back", "Back to Search", Command.BACK, 0)); this.addCommand(this.zoomInCommand = new Command("Zoom in", Command.OK, 1)); this.addCommand(this.zoomOutCommand = new Command("Zoom out", Command.OK, 2)); this.setCommandListener(this); this.gMaps = new GoogleMaps(this.apiKey); map = gMaps.createMap(getWidth(), getHeight(), GoogleStaticMap.FORMAT_PNG); map.setHandler(this); map.setCenter(new GoogleMapsCoordinates(this.lat, this.lon)); GoogleMapsMarker redMarker = new GoogleMapsMarker(new GoogleMapsCoordinates(this.lat, this.lon)); redMarker.setColor(GoogleStaticMap.COLOR_RED); redMarker.setSize(GoogleMapsMarker.SIZE_MID); map.addMarker(redMarker); map.setZoom(15); map.update(); } protected void paint(Graphics g) { map.draw(g, 0, 0, Graphics.TOP | Graphics.LEFT); } /*Other codes i.e. going back to previous display stay here*/ }1 method in public class MapViewer extends Canvas implements GoogleStaticMapHandler,CommandListener { /*Other fields here*/ private String apiKey = "Your-GoogleMap(API-v2)-apiKey" ; public MapViewer(MIDlet midlet, Displayable mainScreen, double lat, double lon) { this.lat = lat; this.lon = lon; this.mainScreen = mainScreen; this.midlet = midlet; this.addCommand(this.backCommand = new Command("Back", "Back to Search", Command.BACK, 0)); this.addCommand(this.zoomInCommand = new Command("Zoom in", Command.OK, 1)); this.addCommand(this.zoomOutCommand = new Command("Zoom out", Command.OK, 2)); this.setCommandListener(this); this.gMaps = new GoogleMaps(this.apiKey); map = gMaps.createMap(getWidth(), getHeight(), GoogleStaticMap.FORMAT_PNG); map.setHandler(this); map.setCenter(new GoogleMapsCoordinates(this.lat, this.lon)); GoogleMapsMarker redMarker = new GoogleMapsMarker(new GoogleMapsCoordinates(this.lat, this.lon)); redMarker.setColor(GoogleStaticMap.COLOR_RED); redMarker.setSize(GoogleMapsMarker.SIZE_MID); map.addMarker(redMarker); map.setZoom(15); map.update(); } protected void paint(Graphics g) { map.draw(g, 0, 0, Graphics.TOP | Graphics.LEFT); } /*Other codes i.e. going back to previous display stay here*/ }2 class. This method will read current latitude, longitude, altitude and return them. Here is the code: Java public static double[] getLocation(LocationProvider lp) throws Exception { double []arr = new double[3]; if(lp != null) { switch(lp.getState()) { case LocationProvider.AVAILABLE: Location l = lp.getLocation(-1); QualifiedCoordinates c = l.getQualifiedCoordinates(); if(c != null ) { double lat = c.getLatitude(); double lon = c.getLongitude(); double alt = c.getAltitude(); String latStr = Double.toString(lat).substring(0,7); String lonStr = Double.toString(lon).substring(0,7); lat = Double.parseDouble(latStr); lon = Double.parseDouble(lonStr); arr[0] = lat; arr[1] = lon; arr[2] = alt; } else { throw new Exception("Co ordinate is null!!"); } break; /* Other cases are handled here */ default: break; } } return arr; } Now when user hits "Locate Me" menu, we just need to call public class MapViewer extends Canvas implements GoogleStaticMapHandler,CommandListener { /*Other fields here*/ private String apiKey = "Your-GoogleMap(API-v2)-apiKey" ; public MapViewer(MIDlet midlet, Displayable mainScreen, double lat, double lon) { this.lat = lat; this.lon = lon; this.mainScreen = mainScreen; this.midlet = midlet; this.addCommand(this.backCommand = new Command("Back", "Back to Search", Command.BACK, 0)); this.addCommand(this.zoomInCommand = new Command("Zoom in", Command.OK, 1)); this.addCommand(this.zoomOutCommand = new Command("Zoom out", Command.OK, 2)); this.setCommandListener(this); this.gMaps = new GoogleMaps(this.apiKey); map = gMaps.createMap(getWidth(), getHeight(), GoogleStaticMap.FORMAT_PNG); map.setHandler(this); map.setCenter(new GoogleMapsCoordinates(this.lat, this.lon)); GoogleMapsMarker redMarker = new GoogleMapsMarker(new GoogleMapsCoordinates(this.lat, this.lon)); redMarker.setColor(GoogleStaticMap.COLOR_RED); redMarker.setSize(GoogleMapsMarker.SIZE_MID); map.addMarker(redMarker); map.setZoom(15); map.update(); } protected void paint(Graphics g) { map.draw(g, 0, 0, Graphics.TOP | Graphics.LEFT); } /*Other codes i.e. going back to previous display stay here*/ }1 method and print the array on display. It's as simple as that. Now, we want to display the location in a map. I am using MidMaps: Google Maps Java ME library. When user hits "Map me" menu, we will set public class MapViewer extends Canvas implements GoogleStaticMapHandler,CommandListener { /*Other fields here*/ private String apiKey = "Your-GoogleMap(API-v2)-apiKey" ; public MapViewer(MIDlet midlet, Displayable mainScreen, double lat, double lon) { this.lat = lat; this.lon = lon; this.mainScreen = mainScreen; this.midlet = midlet; this.addCommand(this.backCommand = new Command("Back", "Back to Search", Command.BACK, 0)); this.addCommand(this.zoomInCommand = new Command("Zoom in", Command.OK, 1)); this.addCommand(this.zoomOutCommand = new Command("Zoom out", Command.OK, 2)); this.setCommandListener(this); this.gMaps = new GoogleMaps(this.apiKey); map = gMaps.createMap(getWidth(), getHeight(), GoogleStaticMap.FORMAT_PNG); map.setHandler(this); map.setCenter(new GoogleMapsCoordinates(this.lat, this.lon)); GoogleMapsMarker redMarker = new GoogleMapsMarker(new GoogleMapsCoordinates(this.lat, this.lon)); redMarker.setColor(GoogleStaticMap.COLOR_RED); redMarker.setSize(GoogleMapsMarker.SIZE_MID); map.addMarker(redMarker); map.setZoom(15); map.update(); } protected void paint(Graphics g) { map.draw(g, 0, 0, Graphics.TOP | Graphics.LEFT); } /*Other codes i.e. going back to previous display stay here*/ }4 class as our current display and pass location data to it so that it can render the map. Java public class MapViewer extends Canvas implements GoogleStaticMapHandler,CommandListener { /*Other fields here*/ private String apiKey = "Your-GoogleMap(API-v2)-apiKey" ; public MapViewer(MIDlet midlet, Displayable mainScreen, double lat, double lon) { this.lat = lat; this.lon = lon; this.mainScreen = mainScreen; this.midlet = midlet; this.addCommand(this.backCommand = new Command("Back", "Back to Search", Command.BACK, 0)); this.addCommand(this.zoomInCommand = new Command("Zoom in", Command.OK, 1)); this.addCommand(this.zoomOutCommand = new Command("Zoom out", Command.OK, 2)); this.setCommandListener(this); this.gMaps = new GoogleMaps(this.apiKey); map = gMaps.createMap(getWidth(), getHeight(), GoogleStaticMap.FORMAT_PNG); map.setHandler(this); map.setCenter(new GoogleMapsCoordinates(this.lat, this.lon)); GoogleMapsMarker redMarker = new GoogleMapsMarker(new GoogleMapsCoordinates(this.lat, this.lon)); redMarker.setColor(GoogleStaticMap.COLOR_RED); redMarker.setSize(GoogleMapsMarker.SIZE_MID); map.addMarker(redMarker); map.setZoom(15); map.update(); } protected void paint(Graphics g) { map.draw(g, 0, 0, Graphics.TOP | Graphics.LEFT); } /*Other codes i.e. going back to previous display stay here*/ } And in the command handler of "Map Me" menu in public static double[] getLocation(LocationProvider lp) throws Exception { double []arr = new double[3]; if(lp != null) { switch(lp.getState()) { case LocationProvider.AVAILABLE: Location l = lp.getLocation(-1); QualifiedCoordinates c = l.getQualifiedCoordinates(); if(c != null ) { double lat = c.getLatitude(); double lon = c.getLongitude(); double alt = c.getAltitude(); String latStr = Double.toString(lat).substring(0,7); String lonStr = Double.toString(lon).substring(0,7); lat = Double.parseDouble(latStr); lon = Double.parseDouble(lonStr); arr[0] = lat; arr[1] = lon; arr[2] = alt; } else { throw new Exception("Co ordinate is null!!"); } break; /* Other cases are handled here */ default: break; } } return arr; }4 class, we write the following code to display current location in Map: Java public void commandAction(Command command, Displayable displayable) { /*Command Handlers for other commands */ if(command == this.getcmdMapMe()) { try { double []arr = Helper.getLocation(this.locationProvider); this.getDisplay().setCurrent (new MapViewer(this,this.mainForm,arr[0],arr[1])); } catch(Exception ex) { this.strLat.setText(ex.getMessage()); } } } At this point, we have the necessary methods to detect location and display them. Job half done! Next is just to save them in database. Let's finish those asap. First let's create a table in database (MySQL): SQL CREATE TABLE IF NOT EXISTS `current_location` ( `id` int(11) NOT NULL AUTO_INCREMENT, `lat` double NOT NULL, `lon` double NOT NULL, `recorded_datetime` datetime NOT NULL, PRIMARY KEY (`id`) ); Here is our method to save the current location: Java public static boolean saveLocation(String baseUrl, double lat, double lon) { InputStream is =null; StringBuffer sb = null; HttpConnection http = null; boolean result = false; try { baseUrl +="&lat=" + Double.toString(lat) + "&lon=" + Double.toString(lon) + "&time=" + Helper.getNowInDate(); baseUrl = Helper.EncodeURL(baseUrl); http = (HttpConnection) Connector.open(baseUrl); http.setRequestMethod(HttpConnection.GET); if (http.getResponseCode() == HttpConnection.HTTP_OK) { sb = new StringBuffer(); int ch; is = http.openInputStream(); while ((ch = is.read()) != -1) { sb.append((char) ch); } result = true; } else { result = false; } } catch (Exception ex) { result = false; } finally { /*Close InputStream & HttpConnection */ } } We also need to write a few lines of server side code to handle this request and save data in the database. I will be using PHP for this purpose. Here it is... Now, we have almost completed one full cycle. That is detecting and saving location in server. However, we are still missing one thing. In the above approach, user needs to click every time in menu to save location, what if we could write a service that will continuously save location (e.g. save location after every five minutes)? That's also possible and in fact very easy to implement with public class MapViewer extends Canvas implements GoogleStaticMapHandler,CommandListener { /*Other fields here*/ private String apiKey = "Your-GoogleMap(API-v2)-apiKey" ; public MapViewer(MIDlet midlet, Displayable mainScreen, double lat, double lon) { this.lat = lat; this.lon = lon; this.mainScreen = mainScreen; this.midlet = midlet; this.addCommand(this.backCommand = new Command("Back", "Back to Search", Command.BACK, 0)); this.addCommand(this.zoomInCommand = new Command("Zoom in", Command.OK, 1)); this.addCommand(this.zoomOutCommand = new Command("Zoom out", Command.OK, 2)); this.setCommandListener(this); this.gMaps = new GoogleMaps(this.apiKey); map = gMaps.createMap(getWidth(), getHeight(), GoogleStaticMap.FORMAT_PNG); map.setHandler(this); map.setCenter(new GoogleMapsCoordinates(this.lat, this.lon)); GoogleMapsMarker redMarker = new GoogleMapsMarker(new GoogleMapsCoordinates(this.lat, this.lon)); redMarker.setColor(GoogleStaticMap.COLOR_RED); redMarker.setSize(GoogleMapsMarker.SIZE_MID); map.addMarker(redMarker); map.setZoom(15); map.update(); } protected void paint(Graphics g) { map.draw(g, 0, 0, Graphics.TOP | Graphics.LEFT); } /*Other codes i.e. going back to previous display stay here*/ }6API. We need to implement public class MapViewer extends Canvas implements GoogleStaticMapHandler,CommandListener { /*Other fields here*/ private String apiKey = "Your-GoogleMap(API-v2)-apiKey" ; public MapViewer(MIDlet midlet, Displayable mainScreen, double lat, double lon) { this.lat = lat; this.lon = lon; this.mainScreen = mainScreen; this.midlet = midlet; this.addCommand(this.backCommand = new Command("Back", "Back to Search", Command.BACK, 0)); this.addCommand(this.zoomInCommand = new Command("Zoom in", Command.OK, 1)); this.addCommand(this.zoomOutCommand = new Command("Zoom out", Command.OK, 2)); this.setCommandListener(this); this.gMaps = new GoogleMaps(this.apiKey); map = gMaps.createMap(getWidth(), getHeight(), GoogleStaticMap.FORMAT_PNG); map.setHandler(this); map.setCenter(new GoogleMapsCoordinates(this.lat, this.lon)); GoogleMapsMarker redMarker = new GoogleMapsMarker(new GoogleMapsCoordinates(this.lat, this.lon)); redMarker.setColor(GoogleStaticMap.COLOR_RED); redMarker.setSize(GoogleMapsMarker.SIZE_MID); map.addMarker(redMarker); map.setZoom(15); map.update(); } protected void paint(Graphics g) { map.draw(g, 0, 0, Graphics.TOP | Graphics.LEFT); } /*Other codes i.e. going back to previous display stay here*/ }7interface and thus code two methods public class MapViewer extends Canvas implements GoogleStaticMapHandler,CommandListener { /*Other fields here*/ private String apiKey = "Your-GoogleMap(API-v2)-apiKey" ; public MapViewer(MIDlet midlet, Displayable mainScreen, double lat, double lon) { this.lat = lat; this.lon = lon; this.mainScreen = mainScreen; this.midlet = midlet; this.addCommand(this.backCommand = new Command("Back", "Back to Search", Command.BACK, 0)); this.addCommand(this.zoomInCommand = new Command("Zoom in", Command.OK, 1)); this.addCommand(this.zoomOutCommand = new Command("Zoom out", Command.OK, 2)); this.setCommandListener(this); this.gMaps = new GoogleMaps(this.apiKey); map = gMaps.createMap(getWidth(), getHeight(), GoogleStaticMap.FORMAT_PNG); map.setHandler(this); map.setCenter(new GoogleMapsCoordinates(this.lat, this.lon)); GoogleMapsMarker redMarker = new GoogleMapsMarker(new GoogleMapsCoordinates(this.lat, this.lon)); redMarker.setColor(GoogleStaticMap.COLOR_RED); redMarker.setSize(GoogleMapsMarker.SIZE_MID); map.addMarker(redMarker); map.setZoom(15); map.update(); } protected void paint(Graphics g) { map.draw(g, 0, 0, Graphics.TOP | Graphics.LEFT); } /*Other codes i.e. going back to previous display stay here*/ }8and public class MapViewer extends Canvas implements GoogleStaticMapHandler,CommandListener { /*Other fields here*/ private String apiKey = "Your-GoogleMap(API-v2)-apiKey" ; public MapViewer(MIDlet midlet, Displayable mainScreen, double lat, double lon) { this.lat = lat; this.lon = lon; this.mainScreen = mainScreen; this.midlet = midlet; this.addCommand(this.backCommand = new Command("Back", "Back to Search", Command.BACK, 0)); this.addCommand(this.zoomInCommand = new Command("Zoom in", Command.OK, 1)); this.addCommand(this.zoomOutCommand = new Command("Zoom out", Command.OK, 2)); this.setCommandListener(this); this.gMaps = new GoogleMaps(this.apiKey); map = gMaps.createMap(getWidth(), getHeight(), GoogleStaticMap.FORMAT_PNG); map.setHandler(this); map.setCenter(new GoogleMapsCoordinates(this.lat, this.lon)); GoogleMapsMarker redMarker = new GoogleMapsMarker(new GoogleMapsCoordinates(this.lat, this.lon)); redMarker.setColor(GoogleStaticMap.COLOR_RED); redMarker.setSize(GoogleMapsMarker.SIZE_MID); map.addMarker(redMarker); map.setZoom(15); map.update(); } protected void paint(Graphics g) { map.draw(g, 0, 0, Graphics.TOP | Graphics.LEFT); } /*Other codes i.e. going back to previous display stay here*/ }9. We will add two commands "Start" and "End" to fulfill this purpose. Whenever location is updated, public class MapViewer extends Canvas implements GoogleStaticMapHandler,CommandListener { /*Other fields here*/ private String apiKey = "Your-GoogleMap(API-v2)-apiKey" ; public MapViewer(MIDlet midlet, Displayable mainScreen, double lat, double lon) { this.lat = lat; this.lon = lon; this.mainScreen = mainScreen; this.midlet = midlet; this.addCommand(this.backCommand = new Command("Back", "Back to Search", Command.BACK, 0)); this.addCommand(this.zoomInCommand = new Command("Zoom in", Command.OK, 1)); this.addCommand(this.zoomOutCommand = new Command("Zoom out", Command.OK, 2)); this.setCommandListener(this); this.gMaps = new GoogleMaps(this.apiKey); map = gMaps.createMap(getWidth(), getHeight(), GoogleStaticMap.FORMAT_PNG); map.setHandler(this); map.setCenter(new GoogleMapsCoordinates(this.lat, this.lon)); GoogleMapsMarker redMarker = new GoogleMapsMarker(new GoogleMapsCoordinates(this.lat, this.lon)); redMarker.setColor(GoogleStaticMap.COLOR_RED); redMarker.setSize(GoogleMapsMarker.SIZE_MID); map.addMarker(redMarker); map.setZoom(15); map.update(); } protected void paint(Graphics g) { map.draw(g, 0, 0, Graphics.TOP | Graphics.LEFT); } /*Other codes i.e. going back to previous display stay here*/ }8method is called where we save the latest location in database. So, think you are traveling and turn this service on, the whole path is saved in database and then in web application you can create cool animations that will traverse the path according to the increasing/decreasing order of time! Well, we are not so far from that. Let's now finish implementing this interface: Java public void locationUpdated(LocationProvider provider, Location location) { if (location != null && location.isValid()) { QualifiedCoordinates qc = location.getQualifiedCoordinates(); boolean isSaved = Helper.saveLocation(URL, qc.getLatitude(), qc.getLongitude()); String text = isSaved == true ? "Location Saved " + ++count : "Failed"; strLat.setText(text); } } public void providerStateChanged(LocationProvider lp, int i) { } Each time a location record is saved, we update a public void commandAction(Command command, Displayable displayable) { /*Command Handlers for other commands */ if(command == this.getcmdMapMe()) { try { double []arr = Helper.getLocation(this.locationProvider); this.getDisplay().setCurrent (new MapViewer(this,this.mainForm,arr[0],arr[1])); } catch(Exception ex) { this.strLat.setText(ex.getMessage()); } } }1variable and print it. So, while running this service, we can have a hint about how many times it has stored record. Now all we need is to register our MapMe MIDlet to public class MapViewer extends Canvas implements GoogleStaticMapHandler,CommandListener { /*Other fields here*/ private String apiKey = "Your-GoogleMap(API-v2)-apiKey" ; public MapViewer(MIDlet midlet, Displayable mainScreen, double lat, double lon) { this.lat = lat; this.lon = lon; this.mainScreen = mainScreen; this.midlet = midlet; this.addCommand(this.backCommand = new Command("Back", "Back to Search", Command.BACK, 0)); this.addCommand(this.zoomInCommand = new Command("Zoom in", Command.OK, 1)); this.addCommand(this.zoomOutCommand = new Command("Zoom out", Command.OK, 2)); this.setCommandListener(this); this.gMaps = new GoogleMaps(this.apiKey); map = gMaps.createMap(getWidth(), getHeight(), GoogleStaticMap.FORMAT_PNG); map.setHandler(this); map.setCenter(new GoogleMapsCoordinates(this.lat, this.lon)); GoogleMapsMarker redMarker = new GoogleMapsMarker(new GoogleMapsCoordinates(this.lat, this.lon)); redMarker.setColor(GoogleStaticMap.COLOR_RED); redMarker.setSize(GoogleMapsMarker.SIZE_MID); map.addMarker(redMarker); map.setZoom(15); map.update(); } protected void paint(Graphics g) { map.draw(g, 0, 0, Graphics.TOP | Graphics.LEFT); } /*Other codes i.e. going back to previous display stay here*/ }7. So we write: Java // to start querying GPS data locationProvider.setLocationListener(MapMe.this, 10, -1, -1); // to stop querying GPS data locationProvider.setLocationListener(null, -1, -1, -1); Yes, it's as simple as that. But there is still one issue, our public static double[] getLocation(LocationProvider lp) throws Exception { double []arr = new double[3]; if(lp != null) { switch(lp.getState()) { case LocationProvider.AVAILABLE: Location l = lp.getLocation(-1); QualifiedCoordinates c = l.getQualifiedCoordinates(); if(c != null ) { double lat = c.getLatitude(); double lon = c.getLongitude(); double alt = c.getAltitude(); String latStr = Double.toString(lat).substring(0,7); String lonStr = Double.toString(lon).substring(0,7); lat = Double.parseDouble(latStr); lon = Double.parseDouble(lonStr); arr[0] = lat; arr[1] = lon; arr[2] = alt; } else { throw new Exception("Co ordinate is null!!"); } break; /* Other cases are handled here */ default: break; } } return arr; }4class implements public void commandAction(Command command, Displayable displayable) { /*Command Handlers for other commands */ if(command == this.getcmdMapMe()) { try { double []arr = Helper.getLocation(this.locationProvider); this.getDisplay().setCurrent (new MapViewer(this,this.mainForm,arr[0],arr[1])); } catch(Exception ex) { this.strLat.setText(ex.getMessage()); } } }4as well and thus handles public static double[] getLocation(LocationProvider lp) throws Exception { double []arr = new double[3]; if(lp != null) { switch(lp.getState()) { case LocationProvider.AVAILABLE: Location l = lp.getLocation(-1); QualifiedCoordinates c = l.getQualifiedCoordinates(); if(c != null ) { double lat = c.getLatitude(); double lon = c.getLongitude(); double alt = c.getAltitude(); String latStr = Double.toString(lat).substring(0,7); String lonStr = Double.toString(lon).substring(0,7); lat = Double.parseDouble(latStr); lon = Double.parseDouble(lonStr); arr[0] = lat; arr[1] = lon; arr[2] = alt; } else { throw new Exception("Co ordinate is null!!"); } break; /* Other cases are handled here */ default: break; } } return arr; }5(i.e. "Map Me" click events). So, when we hit "Start" menu, public void commandAction(Command command, Displayable displayable) { /*Command Handlers for other commands */ if(command == this.getcmdMapMe()) { try { double []arr = Helper.getLocation(this.locationProvider); this.getDisplay().setCurrent (new MapViewer(this,this.mainForm,arr[0],arr[1])); } catch(Exception ex) { this.strLat.setText(ex.getMessage()); } } }6event thread handles this and as long as this thread is not finished, no other button events can not be fired. But as soon as user hits "Start", a pop up dialog box will appear asking for permission to use GPS data. But user will not be able to click it because the public void commandAction(Command command, Displayable displayable) { /*Command Handlers for other commands */ if(command == this.getcmdMapMe()) { try { double []arr = Helper.getLocation(this.locationProvider); this.getDisplay().setCurrent (new MapViewer(this,this.mainForm,arr[0],arr[1])); } catch(Exception ex) { this.strLat.setText(ex.getMessage()); } } }6is not finished yet. A deadlock!! Yes, it is so. So, what we actually have to do is to start and stop listener in different threads: Java // to start querying GPS data // to start querying GPS data new Thread() { public void run() { locationProvider.setLocationListener (MapMe.this, 10, -1, -1); // 10 second interval } }.start(); // to stop querying GPS data new Thread() { public void run() { locationProvider.setLocationListener(null, -1, -1, -1); } }.start(); That's all! We are at the end of developing a mobile application that can save our location in database (not only once, but continuously in a repeated interval and also shows the position in Map). Web ApplicationWe now have lots of GPS traces in database. Let's start to play with those! I have developed two simple applications with these:
Auto Updating Current LocationIf you browse my website, at the right side of my homepage, you will find a map that shows my exact current location. And if I save a location while you are at my homepage, only the map will refresh (as it is implemented in Ajax) and you will experience a sudden move in the map. Isn't that cool? Yes, and it is very easy to implement! All we need is to write some code that will repeatedly look for updated data in the server and as soon as it detects a new record, i.e., if current latitude and longitude do not matches with the previous one, a change has occurred and it will update the map. Let's first write public void commandAction(Command command, Displayable displayable) { /*Command Handlers for other commands */ if(command == this.getcmdMapMe()) { try { double []arr = Helper.getLocation(this.locationProvider); this.getDisplay().setCurrent (new MapViewer(this,this.mainForm,arr[0],arr[1])); } catch(Exception ex) { this.strLat.setText(ex.getMessage()); } } }8 method at the server side: JavaScript function getCurrentLocation() { $strQuery = "select lat, lon, date_format (recorded_datetime, '%M %d %Y %h:%i %p') as recorded_time from current_location order by id desc limit 1"; $resId = executeQuery($strQuery); if($resId) { $data = getRecordsArray($resId); return json_encode(array('lat'=>$data["lat"], 'lon'=>$data["lon"],'time'=>$data["recorded_time"])); } } I have picked the top row (and also the most recent row) from current location table and returned it encoding in json. In the web site, a JavaScript timer will handle it to load the map and keep querying it in a regular interval to detect change. I will write these few lines of JavaScript using jQuery library. Here it is: JavaScript public static double[] getLocation(LocationProvider lp) throws Exception { double []arr = new double[3]; if(lp != null) { switch(lp.getState()) { case LocationProvider.AVAILABLE: Location l = lp.getLocation(-1); QualifiedCoordinates c = l.getQualifiedCoordinates(); if(c != null ) { double lat = c.getLatitude(); double lon = c.getLongitude(); double alt = c.getAltitude(); String latStr = Double.toString(lat).substring(0,7); String lonStr = Double.toString(lon).substring(0,7); lat = Double.parseDouble(latStr); lon = Double.parseDouble(lonStr); arr[0] = lat; arr[1] = lon; arr[2] = alt; } else { throw new Exception("Co ordinate is null!!"); } break; /* Other cases are handled here */ default: break; } } return arr; }0 Location History BrowserHere public void commandAction(Command command, Displayable displayable) { /*Command Handlers for other commands */ if(command == this.getcmdMapMe()) { try { double []arr = Helper.getLocation(this.locationProvider); this.getDisplay().setCurrent (new MapViewer(this,this.mainForm,arr[0],arr[1])); } catch(Exception ex) { this.strLat.setText(ex.getMessage()); } } }9is the CREATE TABLE IF NOT EXISTS `current_location` ( `id` int(11) NOT NULL AUTO_INCREMENT, `lat` double NOT NULL, `lon` double NOT NULL, `recorded_datetime` datetime NOT NULL, PRIMARY KEY (`id`) );0where I am loading the map. So, now if you set this up in your homepage, whenever someone comes to that page, he/she will see your exact location and also get notification of public class MapViewer extends Canvas implements GoogleStaticMapHandler,CommandListener { /*Other fields here*/ private String apiKey = "Your-GoogleMap(API-v2)-apiKey" ; public MapViewer(MIDlet midlet, Displayable mainScreen, double lat, double lon) { this.lat = lat; this.lon = lon; this.mainScreen = mainScreen; this.midlet = midlet; this.addCommand(this.backCommand = new Command("Back", "Back to Search", Command.BACK, 0)); this.addCommand(this.zoomInCommand = new Command("Zoom in", Command.OK, 1)); this.addCommand(this.zoomOutCommand = new Command("Zoom out", Command.OK, 2)); this.setCommandListener(this); this.gMaps = new GoogleMaps(this.apiKey); map = gMaps.createMap(getWidth(), getHeight(), GoogleStaticMap.FORMAT_PNG); map.setHandler(this); map.setCenter(new GoogleMapsCoordinates(this.lat, this.lon)); GoogleMapsMarker redMarker = new GoogleMapsMarker(new GoogleMapsCoordinates(this.lat, this.lon)); redMarker.setColor(GoogleStaticMap.COLOR_RED); redMarker.setSize(GoogleMapsMarker.SIZE_MID); map.addMarker(redMarker); map.setZoom(15); map.update(); } protected void paint(Graphics g) { map.draw(g, 0, 0, Graphics.TOP | Graphics.LEFT); } /*Other codes i.e. going back to previous display stay here*/ }6change. Ok, we are almost at the end of this article. One more interesting thing I will show is the Location History Browser. Our CREATE TABLE IF NOT EXISTS `current_location` ( `id` int(11) NOT NULL AUTO_INCREMENT, `lat` double NOT NULL, `lon` double NOT NULL, `recorded_datetime` datetime NOT NULL, PRIMARY KEY (`id`) );2table consists of all the GPS traces saved in order of time. So, we can easily get the traces for any specific date! The idea is to allow a user to see the traces of any specific date and develop some navigation tools to play with them. First, let's finish a method CREATE TABLE IF NOT EXISTS `current_location` ( `id` int(11) NOT NULL AUTO_INCREMENT, `lat` double NOT NULL, `lon` double NOT NULL, `recorded_datetime` datetime NOT NULL, PRIMARY KEY (`id`) );3 which will return json payload of GPS traces for a specific date: JavaScript public static double[] getLocation(LocationProvider lp) throws Exception { double []arr = new double[3]; if(lp != null) { switch(lp.getState()) { case LocationProvider.AVAILABLE: Location l = lp.getLocation(-1); QualifiedCoordinates c = l.getQualifiedCoordinates(); if(c != null ) { double lat = c.getLatitude(); double lon = c.getLongitude(); double alt = c.getAltitude(); String latStr = Double.toString(lat).substring(0,7); String lonStr = Double.toString(lon).substring(0,7); lat = Double.parseDouble(latStr); lon = Double.parseDouble(lonStr); arr[0] = lat; arr[1] = lon; arr[2] = alt; } else { throw new Exception("Co ordinate is null!!"); } break; /* Other cases are handled here */ default: break; } } return arr; }1 Now we can just call CREATE TABLE IF NOT EXISTS `current_location` ( `id` int(11) NOT NULL AUTO_INCREMENT, `lat` double NOT NULL, `lon` double NOT NULL, `recorded_datetime` datetime NOT NULL, PRIMARY KEY (`id`) );3 with a date and populate the data in map. So, the history browser is done! Wait; there are still some things we are missing. Say I have 50 GPS traces saved for one day and does that actually make any sense to display 50 points in the map? Will it add any value to the user? For a user, these are just random points and how he/she will get idea where I visited on that day? Say, I was at place 'A' at 7 am and at place 'B' at 9 am. These will appear as two points, but no time is attached. Here is what I am going to do to make these really usable to the user:
Now we know what to do! Let's finish the code. exactly meets my user interface requirement. So, here is the code: JavaScript public static double[] getLocation(LocationProvider lp) throws Exception { double []arr = new double[3]; if(lp != null) { switch(lp.getState()) { case LocationProvider.AVAILABLE: Location l = lp.getLocation(-1); QualifiedCoordinates c = l.getQualifiedCoordinates(); if(c != null ) { double lat = c.getLatitude(); double lon = c.getLongitude(); double alt = c.getAltitude(); String latStr = Double.toString(lat).substring(0,7); String lonStr = Double.toString(lon).substring(0,7); lat = Double.parseDouble(latStr); lon = Double.parseDouble(lonStr); arr[0] = lat; arr[1] = lon; arr[2] = alt; } else { throw new Exception("Co ordinate is null!!"); } break; /* Other cases are handled here */ default: break; } } return arr; }2 You can try it out at http://www.amitdutta.net/gpsTraces.php. Pick May,14,15 or June 10, 2011 as these days have lots of traces. If the points are too dense, zoom the map and then start playing! Not Yet Implemented
Using the CodeThere are three simple steps to make the whole system work properly. Here they are:
InstallationBuild the attached "MapMe" project (inside "Codes\MobileApp" directory) and copy "MapMe.jad" and "MapMe.jar" file to your mobile device and install them. For best GPS results, turn on all the GPS positioning methods. In my Nokia N95 8GB, I navigate to "Menu/Tools/Settings/General/Positioning/Positioning methods" and turn on "Assisted GPS", "Integrated GPS" and "Network Based GPS". For Non GPS Mobile DevicesIf your mobile device does not have a built-in GPS, you still can develop a similar application. You need to use CellId (A public static boolean saveLocation(String baseUrl, double lat, double lon) { InputStream is =null; StringBuffer sb = null; HttpConnection http = null; boolean result = false; try { baseUrl +="&lat=" + Double.toString(lat) + "&lon=" + Double.toString(lon) + "&time=" + Helper.getNowInDate(); baseUrl = Helper.EncodeURL(baseUrl); http = (HttpConnection) Connector.open(baseUrl); http.setRequestMethod(HttpConnection.GET); if (http.getResponseCode() == HttpConnection.HTTP_OK) { sb = new StringBuffer(); int ch; is = http.openInputStream(); while ((ch = is.read()) != -1) { sb.append((char) ch); } result = true; } else { result = false; } } catch (Exception ex) { result = false; } finally { /*Close InputStream & HttpConnection */ } }6is a number which is associated with a specific cell (the radio tower to which your handset is connected)) and use open source database of public static boolean saveLocation(String baseUrl, double lat, double lon) { InputStream is =null; StringBuffer sb = null; HttpConnection http = null; boolean result = false; try { baseUrl +="&lat=" + Double.toString(lat) + "&lon=" + Double.toString(lon) + "&time=" + Helper.getNowInDate(); baseUrl = Helper.EncodeURL(baseUrl); http = (HttpConnection) Connector.open(baseUrl); http.setRequestMethod(HttpConnection.GET); if (http.getResponseCode() == HttpConnection.HTTP_OK) { sb = new StringBuffer(); int ch; is = http.openInputStream(); while ((ch = is.read()) != -1) { sb.append((char) ch); } result = true; } else { result = false; } } catch (Exception ex) { result = false; } finally { /*Close InputStream & HttpConnection */ } }6s (such as OpenCellID). I would recommend you read this article and this one for non GPS based phones. What Now?If you have come here, that means you have gone through this long article (I hope you have not just scrolled down here :P). I would like to hear your thoughts about this implementation. Share your ideas, vote if you have liked it and leave a comment... LicenseThis article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL) How to store user location in database?You're going to have to make an ajax call to a script on your server to add the data to your database. You should really try something before asking here though. Come back when you have an issue with your code ;) ... . You don't need Google Maps API to get users geolocation. Check navigator. geolocation.. How can I get current location in PHP?The getCurrentPosition() method is used to get the visitor's position and showLocation() method is used to getting the visitor's address from the getLocation. php file using Ajax. HTML Code: After getting the visitor position, the address will be shown on the web page ( #location span).
How to store location in database MySQL?Ways to persist location data within MySQL. Storing Latitude & Longitude data as Floats or Decimal. This is one of the most fundamental ways of storing geocoordinate data. ... . Spatial Data Types. Spatial types are data types that store geometry data. ... . SRID (Spatial Reference Identifier). How to store latitude and longitude in the database in PHP?My PHP CODE
php $lat = $_GET['lat']; $lng = $_GET['lng']; $sender=$_POST['sender']; $hostname = 'localhost'; $username = 'xxxx'; $password = 'xxxxxxx'; $conn = mysql_connect($hostname,$username,$password) or die('Error Please Try Again.
|