views:

501

answers:

3

Hey all,

I would like to make a Google map overlay with changable pins. An easy way to visualize this would be to think of a near real time overlay, where the pins are constantly changing location.

However, I can't seem to think of a safe way to do this with the ItemizedOverlay. The problem seems to be the call to populate - If size() is called by some maps thread, and then my data changes, then the result when the maps call accesses getItem() can be an IndexOutOfBoundsException.

Can anyone think of a better solution than overloading populate and wrapping super.populate in a synchronized block?

Perhaps I could get better luck using a normal Overlay? The Itemized one seems to exist to manage the data for you, perhaps I am making a fundamental mistake by using it?

Thanks for any help, my brain is hurting!

Hamy

A: 

I've used ItemizedOverlay by subclassing it.

As I understand it (and my application is running perfectly well), you don't modify the populate method. You just have to overload the createItem and size method, so that the ItemizedOverlay class know how to populate the overlay.

Here's a sample (The Circuit object holds my data) :

public class CircuitOverlay extends ItemizedOverlay<Stone> {

private PpMapActivity activity;
private Circuit circuit;
private Drawable marker=null;


public CircuitOverlay(PpMapActivity activity, Circuit circuit) {
    super(PpMapActivity.getStoneDrawable());
    this.marker = PpMapActivity.getStoneDrawable();
    this.activity = activity;
    this.circuit = circuit;
    boundCenter(marker);
    populate();
}


@Override
protected Stone createItem(int i) {
    return circuit.getStone(i);
}

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

public void refresh() {
    populate();
}

@Override
public boolean onTap(int i) {
    Stone stone = circuit.getStone(i);
    if (stone!=null) {
        activity.animateTo(stone);
        activity.editStone(stone);
    }
    return false;
}

}

EDIT : A precision because it seems it wasn't perfectly clear : when the list changes you just have to call the refresh() method.

dystroy
dystroy, Thanks for the answer, but I suppose I did not phrase my question well. Your response is completely correct, but I had already gotten to that stage :) I was trying to make it so that I could change the underlying list of items at any time that I wanted, which turns out to be a lot more complex than I thought it would be. I have solved this, and I can post the solution soon, but it involves giving up the ItemizedOverlay and moving to a standard Overlay
Hamy
Of course I modify frequently my list too ! You still have to do like I say but call <code>populate()</code> when your list change. The <code>refresh()</code> method is indeed there in order to let other classes indicate to the overlay that the underlying circuit has changed... I do it and it works well...
dystroy
A: 

I seem to be having difficulties adding multiple overlay items to the map view. I declare my own ItemizedOverlay class (pretty much the same as in the MapView tutorial on the dev site) but I only see the first marker added. A more thorough description of the problem is on http://www.anddev.org/multiple_overlay_items-t12171.html

Can anyone help me with this? Thanks

Blah...thought I posted this as a comment. Sorry.

Bostjan
+1  A: 

as mentioned in this article

You need to call the following after adding or removing an item from the list.

setLastFocusedIndex(-1);

populate();

Example:

@Override
protected OverlayItem createItem(int i) {
    return overlays.get(i);
}
protected void removeOverlay(OverlayItem o){
    overlays.remove(o);
    setLastFocusedIndex(-1);
    populate();
}
@Override
public int size() {
    return overlays.size();
}
public void addOverlay(OverlayItem o){
    overlays.add(o);
    setLastFocusedIndex(-1);
    populate();
}
Ryan Atherton