0

I'm currently using osmdroid to display current positioning.

Based on the following example i tried to optimize the system a little bit by not constructing the ItemizedOverlay<OverlayItem> and ArrayList<OverlayItem> each time my location is changed, but construct them only once in the constructor, and later on simply add points to my ArrayList variable.

Here's how it looks now:

private void InitializeMarkersOverlay() {
    mOverlayItemArrayList = new ArrayList<OverlayItem>();
    ItemizedOverlay<OverlayItem> locationOverlay =
            new ItemizedIconOverlay<OverlayItem>(this, mOverlayItemArrayList, null);

    mMapView.getOverlays().add(locationOverlay);
}

and when a new location arrives:

private void AddPointToOverlay(GeoPoint gPt, boolean bShouldClearList) {

    OverlayItem overlayItem = new OverlayItem("", "", gPt);
    Drawable markerDrawable = ContextCompat.getDrawable(this, R.drawable.pin);
    overlayItem.setMarker(markerDrawable);

    // first time initializer
    if(bShouldClearList) {
        mOverlayItemArrayList.clear();
    }
    mOverlayItemArrayList.add(overlayItem);
}

Since my mMapView already has a pointer to mOverlayItemArrayList i was hoping that my mapview's layer would be automatically notified regarding the change. but nothing actually happens. Only by recreating the objects, i get to see the pin.

scai
  • 20,297
  • 4
  • 56
  • 72
igal k
  • 1,883
  • 2
  • 28
  • 57

2 Answers2

1

Adding to the list does not work because ItemizedIconOverlay need to do some operations on addition. You can check source code for ItemizedIconOverlay.

You can see there is call to populate() in addItem method (and all other methods which are manipulating with items).

public boolean addItem(final Item item) {
    final boolean result = mItemList.add(item);
    populate();
    return result;
}

But populate() is an implementation detail and is marked as protected so you cannot call it directly.

Correct solution would be:

  1. Don't keep reference to the list but to ItemizedIconOverlay instance.
  2. Use mLocationOverlay.addItem(overlayItem)
  3. You may need to call mapView.invalidate() after adding new point.
Josef Adamcik
  • 5,620
  • 3
  • 36
  • 42
0

I got it working by accessing the overlay directly from the mapview object, not sure why exactly, as i was hoping mMapView.getOverlays() would hold a reference to the ItemizedIconOverlay and its itimized array

if(mMapView.getOverlays().size() > 0) {
            ((ItemizedIconOverlay<OverlayItem>)mMapView.getOverlays().get(0)).removeAllItems();
            ((ItemizedIconOverlay<OverlayItem>)mMapView.getOverlays().get(0)).addItem(overlayItem);
        }
    }
igal k
  • 1,883
  • 2
  • 28
  • 57
  • Your assumption about references is correct. Real reason is that you used addItem method on ItemizedIconOverlay instance. See my response for more details. – Josef Adamcik Aug 10 '17 at 10:37