tags:

views:

352

answers:

2

When I develop an Android map application, I want to draw a circle on the map whose radius is 1 meter. As you known, I can't draw 1 meter directly, I should convert 1 meter to the distance of two pixels depend on the zoom level. How to I convert it, is there anything API I can use.

Canvas.draw(x, y, radius), what value should I put to this method ?

+1  A: 

Three questions you got to ask 1- How big is your map 2- What is your zoom level 3- How big is your screen

Let's make the assumption that the map has the same aspect ratio as your screen (if not then you need to worry about which way to crop (verically vs horizontally) or which way to stretch and then change y our answer to 1)

Once you have the answer 1 and 3 you can work out the ratio between meters and pixels in the 100% zoom case, so you will have a pixels per meter

Next you need to maintain a zoom factor (eg: zoom in double size is 200%)

your call to draw the circle will look like this

 Canvas.draw(x,y, radius_in_meters * pixels_per_meter * zoom_factor/100);
hhafez
+2  A: 

Assuming that your map is Google Maps, they use the Mercator projection, so you'd need to use that for the conversion. Under the Mercator projection, the distance that a pixel represents in meters varies with latitude, so while a meter is a very small distance compared to the Earth radius, latitude is important.

All the examples below are javascript, so you might need to translate them.

Here is a general explanation of the coordinate system:

hXXp://code.google.com/apis/maps/documentation/javascript/maptypes.html#WorldCoordinates

This example contains a MercatorProjection object, which includes the methods fromLatLngToPoint() and fromLatLngToPoint():

hXXp://code.google.com/apis/maps/documentation/javascript/examples/map-coordinates.html

Once you have converted your (x,y) to (lat,lon), this is how you draw a circle:

// Pseudo code
var d = radius/6378800; // 6378800 is Earth radius in meters
var lat1 = (PI/180)* centerLat;
var lng1 = (PI/180)* centerLng;

// Go around a circle from 0 to 360 degrees, every 10 degrees
for (var a = 0 ; a < 361 ; a+=10 ) {
    var tc = (PI/180)*a;
    var y = asin(sin(lat1)*cos(d)+cos(lat1)*sin(d)*cos(tc));
    var dlng = atan2(sin(tc)*sin(d)*cos(lat1),cos(d)-sin(lat1)*sin(y));
    var x = ((lng1-dlng+PI) % (2*PI)) - PI ;
    var lat = y*(180/PI);
    var lon = x*(180/PI);

    // Convert the lat and lon to pixel (x,y) 
}

These two mashups draw a circle of a given radius on the surface of the Earth:

hXXp://maps.forum.nu/gm_sensitive_circle2.html

hXXp://maps.forum.nu/gm_drag_polygon.html

If you choose to ignore the projection then you'd use cartesian coordinates and simply draw the circle using Pythagoras Theorem:

hXXp://en.wikipedia.org/wiki/Circle#Cartesian_coordinates

Marcelo