Search code examples
javaandroidosmdroid

Adding Overlay Items to OSMDroid-Map in AsyncTask


What I want:

I want a map with a marker at the user´s current location and 10 more, loaded in an AsyncTask from a Database after loading the map.

What doenst work

Everything is working fine, except the 10 additional markers. I loaded them from the DB, added them to the List of OverlayItems, and invalidated the map - they still aren´t shown.
Update: works now: By creating the ItemizedIconOverlay after loading the additional Items in an AsyncTask the Items are shown and work as inteded.

Additionally, the List of OverlayItems is initialized with zero objects (obviously), but after I add one OverlayItem, it contains 1 OverlayItem + 11 more null-Objects (or null-Refernces? null-Items? what´s the correct term?)

My Question

1) @ List of OverlayItems: After loading everything, there is still one null-Object, I thought this might cause problems, but it didnt. (Tested with a full List, no difference)
Why is the list initialized with zero items, but when I add one, it contains 12 Items? (11 null, 1 "real" item) (Code below)

2) [SOLVED] As far as I know, if I add OverlayItems to the List and invalidate the map, they should be shown. If I add the Items to a second List, and "overwrite" the first one with the second one, does it still work? (As it´s not the same object anymore, but only a reference to list2, right?)
Update: By creating the ItemizedIconOverlay after loading the additional Items in an AsyncTask the Items are shown and work as inteded.

Full Code
Creating the Map

 mResourceProxy = new DefaultResourceProxyImpl(getApplicationContext());
    mapView.setTileSource(TileSourceFactory.MAPNIK);
    mapView.setBuiltInZoomControls(true);
    mapView.setMultiTouchControls(true);
    mapController = this.mapView.getController();
    mapController.setZoom(25);
    GeoPoint center = new GeoPoint(DataManager.glat, DataManager.glon);
    mapController.setCenter(center);

    // items = null
    items = new ArrayList<OverlayItem>(); // items is still empty
    items.add(new OverlayItem("Here", "SampleDescription", center));
    // now, items contains one OverlayItem, but also 11 empty (null) Items

    this.mLocationOverlay = new ItemizedIconOverlay<OverlayItem>(items,
    new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
                @Override
                public boolean onItemSingleTapUp(final int index,
                        final OverlayItem item) {


                    Intent intent=new Intent();
                    intent.putExtra("newShopName", item.mTitle);
                    intent.putExtra("newShopAdd", item.mDescription);
                    setResult(RESULT_OK, intent);
                    finish(); 

                    return true; 
                }
                @Override
                public boolean onItemLongPress(final int index,
                        final OverlayItem item) {

                    toast = Toast.makeText(ShopChooseActivity.this, item.mTitle + ", " + item.mDescription, Toast.LENGTH_LONG);
                        toast.show();
                        return false;
                    }
                }, mResourceProxy);

        this.mapView.getOverlays().add(this.mLocationOverlay);
        mapView.invalidate();


        loadMap = new LoadChooseShop(ShopChooseActivity.this, items).execute();

Updating the Items with the new List of OverlayItems from AsynTask

items = loadMap.get();
if(items != null)
mapView.invalidate();

Solution

    1. Regarding the new items not showing in the ItemizedIconOverlay - what method are you using to add the items()? For some reason it looks like the addItem(location, item) method does not call populate() so the internal list never gets updated. Use the addItem(item) method for now. I should point out that ItemizedIconOverlay is a user-submitted class and is really just a starting point for a solution.

    2. You mention having nulls in your item list. That is the way Java's ArrayList works. The list is backed by an immutable array so when the backing array is full and you want to add a new item, the list has to create a new larger backing array. Since that is an expensive operation, the new array will be double the size of the old one. The unused "slots" in the backing array are set to null. The only thing that matters is what is returned by mItemList.size().