removing specific overlays from mapview - android

my problem is as follows.
I am creating multiple itemized overlays. (because every overlay gets a different drawable)
I customized the itemized overlay class, but when i add it to the mapview overlays, the class is transformed into an overlay class.
to make it worse i got 3 classes creating overlays on the same map. each class represents an item on the map with it's own intelligence behind it.
the problem i now have is that i want to remove an overlay, but i can not be sure that the index i inserted it on, is also the index it has when i try to remove it. (the other classes might have inserted an overlay in the mean time)
the classes are self updating, so i do not want a solution that fires an update or delete event from the main class. (the whole point is to add a class and forget about it)
so my question would be: how can i identify which layer is which when i want to call a remove on that layer. i think the information is available, but i do not know how to get to it.
this is the code i am using to add the overlay
OverlayItem overlayitem = new OverlayItem(p,myNaam ,myOmschrijving );
LocationOverlay = new MyLocationOverlay(drawable, myContext);
LocationOverlay.SetLocation(i,overlayitem);
myOverlays.add(LocationOverlay);

You can set a certain integer as a position for every overlays
something like that :
mapView.getOverlays().add(0,myScaleBarOverlay);
and when you want ro remove this call:
mapView.getOverlays().remove(0);
mapView.invalidate();
Regard

You don't have to remove specific layer. You can remove an overlay specified by it's reference (e.g. myOverlay).
LocationOverlay myOverlay = new MyLocationOverlay(drawable, myContext); //`you forgot the name of variable`
mapView.getOverlays().remove(myOverlay);

Related

Redraw only being called on ClusterItems that have received position updates

It appears that Google Maps API does some magic in the background that prevents ClusterItems from being updated unless they've received positional updates.
Unfortunately, that means if I want to change my markers' appearance at different zoom levels, the appearance won't be refreshed until the markers receive new position data.
Is there any way to get around this?
I'm currently doing my map refresh this way:
HashSet<customClusterItem> limitedDisplaySet = new HashSet<>();
mClusterManager.clearItems();
//...build limitedDisplaySet
mClusterManager.addItems(limitedDisplaySet);
mClusterManager.cluster();
I ended up fixing this problem by creating a copy constructor for my ClusterItem and copying my list of ClusterItems when I need to perform a redraw on them outside of the de-clustering event.
The reason this works is because the default ClusterRenderer keeps a cache of all the markers it has already drawn. When we make a copy of a ClusterItem, it is considered a new object in the ClusterRenderer's cache, which means the renderer needs to draw a new Marker to represent the object. This emulates a "redraw" of the original Marker.

How to manage Markers well using google maps api v2 on android

I'm trying to implement app in which you can add your own marker which will be given a shutdown time. To do so I need to know how to manage my markers. Let's say I have array list of users with assigned unique ID.
private ArrayList<User> userList = new ArrayList<>();
Then I will create array list of markers which will contain information like Latitude, Longitude, Title, owner's ID and deadline.
private ArrayList<MyMarker> mMarkersArray = new ArrayList<MyMarker>();
Next whenever user will activate add marker method, new marker will be pushed to my list of markers. Ideologically everything seems nice and easy, furthermore creating new object looks like this:
Marker mMarker = mMap.addMarker(new MarkerOptions() (...) );
but when it comes to managing specific markers it seems like I'm missing something. There will be some trigger method which will check the deadline of all markers (or rather first one on the 'sorted by deadline' list) and then it should remove (not hide, because I think it would be inefficient from the memory point of view). How to achieve this? I can't add some custom variable like ID to markers (so I could then find the one I'm interested in) and I'm a bit lost.
There is a way to achieve this by clearing whole map and then rendering again all markers except the inactive, but as far as I'm concerned it's very inefficient and there has to be better solution.
If you want to remove a specific marker from the map, you can just call the remove(). method.
Sample code to remove a marker from MapView and HashMap:
for (Marker marker : hm.keySet()) {
if (hm.get(marker).equals(deadline)) {
marker.remove();
hm.remove(marker);
}
}
You dont need to clear the entire MapView, if you just call remove() method on specific marker.

Custom OverlayItem not drawing

I created a custom OverlayItem class so that I could essentially have one kind of OverlayItem whose Drawable marker would set itself depending on the state of some data that I pass into it.
I have attempted to accomplish this by, on my first attempt, utilizing the setMarker method within the OverlayItem class. Once that did not work I attempt to override the getMarker method and have it return the appropriate marker to represent the data.
Both of these attempts ended with nothing being drawn on the map...however if they are commented out the markers draw just fine (except they of course use the default marker, which isn't what I want).
Here is my code for my custom OverlayItem class (the commented out methods I have tried and they have not worked):
private class MyOverlayItem extends OverlayItem {
private Context mContext;
private MyData mData;
public MyOverlayItem(GeoPoint point, MyData data, Context context) {
super(point, data.getWhat(), data.getWhere());
this.mContext = context;
this.mData = data;
/*if(data.getTemp() > 200)
this.setMarker(res.getDrawable(R.drawable.icon_data_hot_l));
else if(data.getTemp() > 100)
this.setMarker(res.getDrawable(R.drawable.icon_data_neutral_l));
else
this.setMarker(res.getDrawable(R.drawable.icon_data_frozen_l));*/
}
/*#Override
public Drawable getMarker(int stateBitset) {
Resources res = this.mContext.getResources();
if(this.mData.getTemp() > 200)
return res.getDrawable(R.drawable.icon_data_hot_l);
else if(this.mData.getTemp() > 100)
return res.getDrawable(R.drawable.icon_data_neutral_l);
return res.getDrawable(R.drawable.icon_data_frozen_l);
}*/
}
Is there a way to do what I am attempting to do...or do I need to make a unique OverlayItem class corresponding to each state of my data? (Ew.)
I have been able to make the markers appear, however they are appearing upside-down (at least, I think they are, it may just be that their shadow is at the top-left rather than the bottom-right).
All I needed to do was add this line:
this.mMarker.setBounds(0, 0, this.mMarker.getIntrinsicWidth(), this.mMarker.getIntrinsicHeight());
...as well as this line to correctly orient the markers (I added this when my ItemizedOverlay adds tan overlay item:
overlay.setMarker(boundCenterBottom(overlay.getMarker(0)));
The API states that the Marker needs bounds to be displayed...
#celestialorb Either one of your snippets does the job alone (or mine worked with either anyway)
when you use setBounds() alone, you get what you tell it to do... the bounding box for your marker is set. The orientation to the OverlayItem's Point and shadow state of the Marker, etc are set to default (didn't look those up, but they don't do what I want...) :)
mOverlay.setMarker(boundCenterBottom(mOverlay.getMarker(0))); does the complete job for you, setting the bounds and centering the bottom of the Marker on the Point (hence the stylish Method name).
Now, as to best practices, Brighter bulbs than I will have to chime in...
Try overriding the onDraw() method of your overlay class.
Here is another approach:
GoogleMaps: custom ItemizedOverlay and OverlayItem, the correct way to show different marker
I think I prefer this answer though... thanks!

How to pass Itemized Overlay from a class to a Listener Class

I tried searching the forums on this one, but I wasn't able to find anything on my problem.
To describe my problem, everytime my location changes, it redraws the center maker on the map.... Only catch is that it doesn't delete the previous one. I can get it to delete the previous one when the location is changed, but I have no idea how to pass the original overlay in-between classes.
Also, pastebin here
Thanks in advance,
hwrd
You need to clear "existing" items in the Overlay list before adding new ones.
public void createOverlay(GeoPoint point, MapView mv)
{
//Make overlay reference declaration
List mapOverlays = mv.getOverlays();
Drawable drawable = this.getResources().getDrawable(R.drawable.center_marker);
FindScreenOverlays itemizedoverlay = new FindScreenOverlays(drawable);
OverlayItem overlayitem = new OverlayItem(point,null,null);
//clear your list before adding new overlays unless you want to see all the previous locations as well.
itemizedoverlay.addOverlay(overlayitem);
mapOverlays.add(itemizedoverlay);
}
Adding an OverlayItem is similar to adding an overlay. Just extend ItemizedOverlay. ( public class YourItemizedOverlay extends ItemizedOverlay )

Equivalent of com.google.android.maps.ItemizedOverlay.populate() for OpenStreeMaps (OSMDroid)

Any idea what's the equivalent of com.google.android.maps.ItemizedOverlay.populate() method in case of OpenSteeMapViewItemizedOverlay ?
There doesn't seem to be one. The data you pass into the constructor is already a list of OverlayItem objects. In the standard ItemizedOverlay, you must call populate(), so that the overlay iterates over the list of data and calls createItem() to create OverlayItems for each piece of data but in OpenstreetMapViewItemizedOverlay you have already create the OverlayItems so you don't need that step. The drawback I see though is that you cannot change the overlay once you create it though.

Categories

Resources