7

I am trying to replicate this feature of Maps in Android: Custom Map Overlay

You can see that on the map, there's a Circle depicting the range that the user has selected.

In my application, I'll also want a dragger to reside on the perimeter of the circle, which can be dragged to redefine radius.

If someone could tell me how to draw custom drawable overlays and 2D graphics over map, I can do other things on my own.

Thanks!

The full application can be reached at this link

Aman Alam
  • 11,231
  • 7
  • 46
  • 81
  • Check out this library, it has exactly this functionality: https://github.com/i-schuetz/map_areas – User Oct 14 '14 at 21:39

3 Answers3

18

Okay, I tried to do things on my Own, and put this code to get the above effect:

public class MarkerOverlay extends Overlay {

    Geocoder geoCoder = null;

    public MarkerOverlay() {
        super();
    }


    @Override
    public boolean onTap(GeoPoint geoPoint, MapView mapView){
        selectedLatitude = geoPoint.getLatitudeE6(); 
        selectedLongitude = geoPoint.getLongitudeE6();
        return super.onTap(geoPoint,mapView);
    }

    @Override
    public void draw(Canvas canvas, MapView mapV, boolean shadow){

        if(shadow){
            Projection projection = mapV.getProjection();
            Point pt = new Point();
            projection.toPixels(globalGeoPoint,pt);

            GeoPoint newGeos = new GeoPoint(selectedLat+(100),selectedLong); // adjust your radius accordingly
            Point pt2 = new Point();
            projection.toPixels(newGeos,pt2);
            float circleRadius = Math.abs(pt2.y-pt.y);

            Paint circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);

            circlePaint.setColor(0x30000000);
            circlePaint.setStyle(Style.FILL_AND_STROKE);
            canvas.drawCircle((float)pt.x, (float)pt.y, circleRadius, circlePaint);

            circlePaint.setColor(0x99000000);
            circlePaint.setStyle(Style.STROKE);
            canvas.drawCircle((float)pt.x, (float)pt.y, circleRadius, circlePaint);

            Bitmap markerBitmap = BitmapFactory.decodeResource(getApplicationContext().getResources(),R.drawable.pin);
            canvas.drawBitmap(markerBitmap,pt.x,pt.y-markerBitmap.getHeight(),null);

            super.draw(canvas,mapV,shadow);
        }
    }
}

This let me have following effect:

Effect on Map

The calculation used may not be what you want.
Its just for demonstration purposes.
Real range/distance calculation requires the use of bearing too and has some specific formula.
Let me know if you have any questions regarding this.

Aman Alam
  • 11,231
  • 7
  • 46
  • 81
  • what is selectedlatitude and longidute? where have you used latitude,longitude values ? please guide i want to implement same thing. – UMAR-MOBITSOLUTIONS Apr 16 '11 at 12:04
  • and please paste code of its usage from google map. how you call this class any help would be appreciated. – UMAR-MOBITSOLUTIONS Apr 16 '11 at 12:16
  • Sorry, it is the latitude/longitude the user tapped on. its a global variable which holds these values. This class is an Inner class of my `MapActivity` – Aman Alam Apr 17 '11 at 08:06
  • 2
    how you call it from google map? to create this current overlay item can you please add that code also so that i can utilize it? – UMAR-MOBITSOLUTIONS May 01 '11 at 11:49
  • 1
    While you add the overlay, use this class. and the `onDraw()` method will always be called whenever Android draws map tiles (on zoom, pan etc) – Aman Alam May 01 '11 at 17:18
  • @Sheikh Aman Hi, Sheikh Aman I also want this type circle means according to distance when map will zoom then circle radius will also increase and map in zoom out then again radius of circle will decrease. Now i am able to draw circle but I dont know what to do for above query – Niranj Patel Oct 05 '11 at 11:34
  • You should be able to do this with the above code, since this is what I have been doing – Aman Alam Oct 07 '11 at 06:38
  • @SheikhAman thanks it is working.. but i need to do more calculation as per my requirement by the way thanks and nice answer ... – Niranj Patel Oct 10 '11 at 12:14
  • @SheikhAman What my scenario is i want to implement this thing in my Application in Mapview , I have prepared a custom gallery which will display all the thumbnails of the gallery image or video when i choose them what i want to do is that i want to display that image in my mapview i mean what ever images i have selected from gallery that images small thumbnails instead of pin i want to display in mapview how can i do that i am not able to understand please if u have any refrence link.... – Jay Thakkar Sep 19 '12 at 08:16
  • What to import to be able to extend Overlay? – portfoliobuilder Aug 31 '16 at 18:28
1

Extend the class ItemizedOverlay to override the draw() method. The Canvas where overlays are drawn is passed to that method and you can call drawCircle or anything that's needed to make your range dragger appear.

ognian
  • 11,451
  • 4
  • 35
  • 33
  • This is a good option, but as it can be seen in the image above, I'll need to have the points where a marker currently is. first it will give me geoPoints, and I'll have to convert them into screen-pixel format (co-ordinates like x,y) i can't anything for that! :-/ – Aman Alam Dec 15 '10 at 13:26
  • Check this out: http://code.google.com/android/add-ons/google-apis/reference/com/google/android/maps/MapView.html#getProjection%28%29 – ognian Dec 15 '10 at 14:52
  • Cool.. i got the mouse points. however, Since I am also using the onTap method to put a marker at the position where user clicks, after overriding the draw() method, onTap mechanism isn't working. Because it used to call the default draw() method for putting up markers, which I have overridden now. Any solution to this!? – Aman Alam Dec 17 '10 at 06:11
0

An example code to draw a pushpin with the circle:

public class MapDemoActivity extends MapActivity {
    MapView mapView;
    MapController mc;
    GeoPoint p;

    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    mapView = (MapView) findViewById(R.id.mapView);
    LinearLayout zoomLayout = (LinearLayout)findViewById(R.id.zoom);  
    View zoomView = mapView.getZoomControls(); 

    zoomLayout.addView(zoomView, 
        new LinearLayout.LayoutParams(
            LayoutParams.WRAP_CONTENT, 
            LayoutParams.WRAP_CONTENT)); 
    mapView.displayZoomControls(true);

    mc = mapView.getController();        
    String coordinates[] = {"28.38", "77.12"};
    double lat = Double.parseDouble(coordinates[0]);
    double lng = Double.parseDouble(coordinates[1]);

    p = new GeoPoint(
        (int) (lat * 1E6), 
        (int) (lng * 1E6));

    mc.animateTo(p);
    mc.setZoom(8); 
    //---Add a location marker---
    MapOverlay mapOverlay = new MapOverlay();
    List<Overlay> listOfOverlays = mapView.getOverlays();
    listOfOverlays.clear();
    listOfOverlays.add(mapOverlay);        
    mapView.invalidate();
    }

    class MapOverlay extends com.google.android.maps.Overlay
{
    @Override
    public boolean draw(Canvas canvas, MapView mapView, 
    boolean shadow, long when) 
    {
        super.draw(canvas, mapView, shadow);                   

        //---translate the GeoPoint to screen pixels---
        Point screenPts = new Point();
        mapView.getProjection().toPixels(p, screenPts);
        //--------------draw circle----------------------            

        Point pt=mapView.getProjection().toPixels(p,screenPts);

        Paint circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        circlePaint.setColor(0x30000000);
        circlePaint.setStyle(Style.FILL_AND_STROKE);
        canvas.drawCircle(screenPts.x, screenPts.y, 50, circlePaint);           

        //---add the marker---
        Bitmap bmp = BitmapFactory.decodeResource(
            getResources(), R.drawable.pin);            
        canvas.drawBitmap(bmp, screenPts.x, screenPts.y-bmp.getHeight(), null);              
        super.draw(canvas,mapView,shadow);

        return true;

    }
}
@Override
protected boolean isRouteDisplayed() {
    // TODO Auto-generated method stub
    return false;
}
}
Monica M
  • 161
  • 3
  • 12
  • HI manaco ..while running I have some doubts in your code. for zoom functionality there is button zoom or any? – NovusMobile Feb 20 '12 at 11:27
  • @denny I have used zoom controls in main.xml Refer this link for more on map [link](http://mobiforge.com/developing/story/using-google-maps-android) – Monica M Feb 21 '12 at 12:56