yet another blog about computer, technology, programming, and internet

Showing posts with label GWT. Show all posts
Showing posts with label GWT. Show all posts

Thursday, February 03, 2011

GWT and Delayed Execution for Google Maps Geocoding

Thursday, February 03, 2011 Posted by Ismail Habib , 25 comments
Google Maps provide us with an asynchronous way of doing a geocoding, which is pretty much how GWT is dealing with all type of client-server communication. However, sometimes we need a way to synchronize them. By synchronizing I mean waiting for the required asynchronous call to return a value before continue with other execution. Using something like Timer to wait for a reply doesn't work since it will only block the whole process on the browser since JavaScript interpreter is single-threaded. Fortunately, there is a way to deal with it within GWT by using DeferredCommand.

I'm going to take an example of using Geocoding from Google Maps. What I would like to do is geocode two address into latitude, longitude coordinate and use them as parameters for another method.

Geocoder geocode = new Geocoder();
final Callback firstCallback = new Callbak();
geocode.getLatLng("Jl. Tb Ismail Bandung Indonesia", firstCallback);
final Callback secondCallback = new Callbak();
geocode.getLatLng("Jl. Ganesha Bandung Indonesia", secondCallback);
final Command command = new Command() {
   @Override
   public void execute(){
      if ((firstCallback.location != null) 
            && (secondCallback.location != null)) {
         //call the method
         anotherMethod(firstCallback.location, secondCallback.location);
      } else {
         DeferredCommand.addCommand(this); //delay execution
      }
   }
}
command.execute();

With "Callback" as a class to temporarily store value from geocode.

class Callback implements LatLngCallback {
   public LatLng location;

   @Override
   public void onFailure() {
      //put something here
   }

   @Override
   public void onSuccess(LatLng point) {
      location = point;
   }
}

This works for me well, however, I do realize that DeferredCommand is now deprecated. Any other solution?

Friday, April 23, 2010

Drawing Circle on Google Maps using GWT

Friday, April 23, 2010 Posted by Ismail Habib , , , 50 comments
I was a bit surprised to realize that Google Maps API does not provide us with a circle overlay. Oh well, I believe they will do that someday. As for now, we just have to be satisfied with what we have.

We can do this in two ways. Drawing circle is easy. By using an image of circle and stretch it to the right size, or by using Polygon Overlay and approximate a circle. The most difficult thing is we have to be able to do transformation of points to latitude/longitude coordinate. No need to reinvent the wheel, somebody else have pointed out how to do this kind of things. Check out these two links:
Drawing circle on Google Maps with an image
Drawing circle on Google Maps with an approximation (using Polygon)

However, these two codes are written for JavaScript. I'm using the knowledge provided by both to rewrite it for GWT. I'm using the approximation method, but it should be easy for you if you want to use image instead of Polygon.

public void drawCircleFromRadius(LatLng center, double radius,
   int nbOfPoints) {

 LatLngBounds bounds = LatLngBounds.newInstance();
 LatLng[] circlePoints = new LatLng[nbOfPoints];

 double EARTH_RADIUS = 6371000;
 double d = radius / EARTH_RADIUS;
 double lat1 = Math.toRadians(center.getLatitude());
 double lng1 = Math.toRadians(center.getLongitude());

 double a = 0;
 double step = 360.0 / (double) nbOfPoints;
 for (int i = 0; i < nbOfPoints; i++) {
  double tc = Math.toRadians(a);
  double lat2 = Math.asin(Math.sin(lat1) * Math.cos(d) + Math.cos(lat1)
    * Math.sin(d) * Math.cos(tc));
  double lng2 = lng1
    + Math.atan2(Math.sin(tc) * Math.sin(d) * Math.cos(lat1),
     Math.cos(d) - Math.sin(lat1) * Math.sin(lat2));
  LatLng point = LatLng.newInstance(Math.toDegrees(lat2), Math
   .toDegrees(lng2));
  circlePoints[i] = point;
  bounds.extend(point);
  a += step;
 }

 Polygon circle = new Polygon(circlePoints, "white", 0, 0, "green", 0.5);

 map.addOverlay(circle);
}