Creating Custom Overlay on the map
Asked Answered
S

3

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

Spurtle answered 13/12, 2010 at 12:19 Comment(1)
Check out this library, it has exactly this functionality: github.com/i-schuetz/map_areasSolana
S
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.

Spurtle answered 21/1, 2011 at 11:56 Comment(10)
what is selectedlatitude and longidute? where have you used latitude,longitude values ? please guide i want to implement same thing.Fourchette
and please paste code of its usage from google map. how you call this class any help would be appreciated.Fourchette
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 MapActivitySpurtle
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?Fourchette
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)Spurtle
@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 queryDiella
You should be able to do this with the above code, since this is what I have been doingSpurtle
@SheikhAman thanks it is working.. but i need to do more calculation as per my requirement by the way thanks and nice answer ...Diella
@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....Jointworm
What to import to be able to extend Overlay?Sherfield
S
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.

Sidonia answered 13/12, 2010 at 12:55 Comment(3)
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! :-/Spurtle
Check this out: code.google.com/android/add-ons/google-apis/reference/com/…Sidonia
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!?Spurtle
M
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;
}
}
Marquettamarquette answered 18/2, 2012 at 11:17 Comment(2)
HI manaco ..while running I have some doubts in your code. for zoom functionality there is button zoom or any?Semple
@denny I have used zoom controls in main.xml Refer this link for more on map linkMarquettamarquette

© 2022 - 2024 — McMap. All rights reserved.