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

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);
}