androidgoogle-mapsitemizedoverlayoverlayitem

GoogleMaps: custom ItemizedOverlay and OverlayItem, the correct way to show different marker


I've been searching long for clear informations about the right way of extending ItemizedOverlay and OverlayItem, but the result I get does not satisfy me yet. In a few words, I need to show on a map different kind of markers related to a number of locations; the type of the marker to be displayed is determined by specific properties of the location itself. I will also need to display a certain marker when a marker is selected, and another one when the marker is unselected or unfocused. According to what I understand, this is what I wrote:

public class MyItemizedOverlay extends ItemizedOverlay<MyOverlayItem> {

ArrayList<MyOverlayItem> items;
//...

public MyItemizedOverlay(Drawable drawable, /*...*/) {
    super(boundCenterBottom(drawable));
    //...
    populate();
}

public void addOverlay(MyOverlayItem overlay) {
    return this.items.add(overlay);
    populate();

@Override 
protected MyOverlayItem createItem(int index) {
    return this.items.get(index);
}

@Override
public int size() {
    return this.items.size();
}}

    public class MyOverlayItem extends OverlayItem {

//...

public Drawable getMarker(int stateBitset) {
    Drawable drawable;
    try {
        if (stateBitset == 0) {
            if (this.property.Equals("ON")) {
                drawable = this.context.getResources().getDrawable(R.drawable.on);
                drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
                return drawable;
            } else if (this.property.Equals("OFF")) {
                drawable = this.context.getResources().getDrawable(R.drawable.off);
                drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
                return drawable;
            } else {
                drawable = this.context.getResources().getDrawable(R.drawable.generic);
                drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
                return drawable;
            }
        } else {
            //same thing as above, just with different drawables.
        }
    } catch (Exception e) {
        //...
    }

    return null;
}

MyItemizedOverlay is created and populated of MyOverlayItem in the main MapActivity. Now: the only markers correctly placed are the default ones. That is, the ones which have as drawable the one passed to the constructor of MyItemizedOverlay, and is set with boundCenterBottom (which set the middle bottom point of the image to point to the specified point in the map). When the getMarker method in MyOverlayItem class does not return null, and another marker is used, the image is displayed wrongly (for example, the shadow does not follow the image!). In getMarker method, you must define a bounding box for the drawable (with drawable.setBounds); but I think that in this way, however, you do not specify what should be the point that has to be placed in the point of the map.

Thus, the question is: how can I specify, for a marker drawable returned from the getMarker method of an OverlayItem object to a ItemizedOverlay, the bounds to be used to be placed in the map (as done with boundCenterBottom in MyItemizedOverlay for the default drawable)? And what is the best way to do it?

;)


Solution

  • Ok, after repeated tests it seems that this:

    drawable.setBounds(-drawable.getIntrinsicWidth()/2, -drawable.getIntrinsicHeight(), drawable.getIntrinsicWidth() /2, 0);
    

    placed in the getMarker method of OverlayItem for the drawable that has to ber returned does the job (as boundBottomCenter does in ItemizedOverlay). Now all is working fine, and even the non-default markers are displayed correctly.

    Cheers!