cgr cgr - 15 days ago 4
Android Question

How to get number of pixels equals to a radius of Geozone circle according to zoom level? OR Radius of zone circle to screen pixels?

I am creating Geozones on google map. Default Circle that map API provides is laggy when scroll the map. So, I wanted to create my own circle (overlay on map). I created circle with radius of 300 meters which is fixed. The width of this circle should change according to the zoom level as the default map circle does. I have writen a method as below that calculates pixels by taking Radius and Zoom level as parameters. I have added the default circle also to verify the accuracy of my circle for different addresses.

//Adjusts the width and height of circle according to radius and zoom level
private void adjustCircleWidth(final LatLng center, final double zoom) {
//With inputs from topic "Zoom" from https://developers.google.com/maps/documentation/android-api/views
double widthOfWorldDP = 256 * Math.pow(2, zoom);

int radius = 300; //meters.
int circleWidthMeters = radius * 2; // *2 to get diameter or width.

//From google and alsop from this SOF post http://stackoverflow.com/a/6452332/3209739
int EQUATOR_LENGTH_METERS = 40075004; //in meters..

float dpOfCircle = (float) ((widthOfWorldDP * circleWidthMeters) / EQUATOR_LENGTH_METERS);

//converts dp to pixels depending on device density..
int pixels = (int) convertDpToPixels(dpOfCircle);

mCircleView.requestLayout();
mCircleView.getLayoutParams().height = pixels;
mCircleView.getLayoutParams().width = pixels;
}


Well, this works fine. I started verifying for other locations then it started showing variations. Circle width is smaller than the map's default circle. I analysed it to understand that it show perfectly (in sync with default circle) when I set the circle around any location that is on Equator..for exampple circle is in perfect sync with default for Kenya as location as Kenya is on equator..see the attached scrrenshot. If I keep move away from equator, the circle goes smaller and smaller from the default circle. Say, for Germany as location circle is almost half of the default one...see the attached scrrenshot.

This is because formula I used is tied to equator.

Can you help with any clue on how can I make it uniform ?

cgr cgr
Answer

Credits to and thanks a ton to Android Maps API v2 draw circle post.

I could calculate the width of circle in pixels given latitude, longitude and radius (from given lat, long) in meters.

private int convertZoneRadiusToPixels(double lat, double lng, double radiusInMeters) {
    double EARTH_RADIUS = 6378100.0;
    double lat1 = radiusInMeters / EARTH_RADIUS;
    double lng1 = radiusInMeters / (EARTH_RADIUS * Math.cos((Math.PI * lat / 180)));

    double lat2 = lat + lat1 * 180 / Math.PI;
    double lng2 = lng + lng1 * 180 / Math.PI;

    Point p1 = mMap.getProjection().toScreenLocation(new LatLng(lat, lng));
    Point p2 = mMap.getProjection().toScreenLocation(new LatLng(lat2, lng2));
    return Math.abs(p1.x - p2.x);
}