Unique marker ID for arraylist - android

What I am trying to do is when someone clicks on a marker on the google map, I need to get the info on that marker from my ArrayList and then pass it on to the next activity so I can display additional details about that marker. The only options that I know of when it comes to markers is getSnippet, getTitle and getPosition. Is there a way to assign a unique key to the marker so I can pull it from my list? Reason for this is there could be two markers with the same name. Right now it doesn't even find the marker by name when I do a search for it.
// WHEN A USER CLICKS A MAKER ON THE MAP
#Override
public void onInfoWindowClick(Marker marker)
{
// TESTING TO SEE WHAT MY VALUE WOULD BE IN THE LIST RETURNS - TEST MARKER
// DISPLAY ON SCREEN SO I CAN SEE WHAT THE VALUE IS
Toast.makeText(this, "Found " + marker.getTitle(), Toast.LENGTH_SHORT).show();
// SEARCH MY LIST FOR VALUE
for(int i = 0; i < marker_list.size(); i++)
{
// IF THIS VALUE IS SAME AS MARKER TITLE
String value = marker_list.get(i);
if(value == marker.getTitle())
{
Toast.makeText(this, "Found " + value,Toast.LENGTH_SHORT).show();
break;
}
}
}

How about marker.toString() ?
Instead of using an ArrayList to store the markers and running through the list to find your value, you could use a HashMap. When you add your markers, you put marker.toString() as the key and whatever information you want to associate with the marker as the value into the HashMap.
By the way: you're method to find the clicked marker is probably not working because of the way you compare Strings:
value == marker.getTitle()
This checks if two String references are the exact same String object. To compare the String values, do
value.equals(marker.getTitle())

Related

android-maps-extensions infoWindow doesn't show

I need display >100 markers on the map and show info window after click on marker.
I have used android google maps api v2, but it is lagging with such number of markers. So I decided switch to android-maps-extensions. After I did it info window has stopped appear after click on marker.
Here is my code:
private void prepareMap() {
SupportMapFragment fragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.locationsMap);
map = fragment.getExtendedMap();
ClusteringSettings settings = new ClusteringSettings();
settings.clusterOptionsProvider(new ClusterOptionsProvider() {
#Override
public ClusterOptions getClusterOptions(List<Marker> markers) {
float hue = BitmapDescriptorFactory.HUE_RED;
BitmapDescriptor icon = BitmapDescriptorFactory.defaultMarker(hue);
return new ClusterOptions().icon(icon);
}
});
settings.clusterSize(100);
settings.addMarkersDynamically(true);
map.setClustering(settings);
map.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker) {
// breakpoint here are working. marker is not null
marker.showInfoWindow();
return false;
}
});
}
public void onLoadFinished(android.support.v4.content.Loader loader, Cursor cursor) {
if (map != null) {
cursor.moveToFirst();
int count = cursor.getCount();
for (int i = 0; i < count; i++) {
Location location = new Location(cursor);
MarkerOptions options = new MarkerOptions();
options.position( new LatLng(location.getLatitude(), location.getLongitude()));
options.title(location.getTitle()); // title is not null
options.snippet(location.getAddress()); // address is not null
options.data(location);
map.addMarker(options);
cursor.moveToNext();
}
}
}
Any suggestions? I have try use own InfoWindowAdapter, but it is not scaling this window for appropriate content, however I am using wrap_content attribute in xml.
As there is no support for setting title on ClusterOptions (yet), you will have to use InfoWindowAdapter (you may put a separate question on why it is not working as you want it) or add title to ClusterOptions yourself and make sure its value is forwarded to virtual marker that represents cluster. This sounds complicated but is fairly easy. You may also want to add issue on GitHub regarding title not being supported for clustrers.
After that you may use something like:
return new ClusterOptions().icon(icon).title("Test");
Then you will have to figure out what title will best fit your needs. You will most likely want to use List<Marker> to calculate title for this group of markers.
Note: If you zoom enough to show separate markers, you can click on them to show title. If not, there is something more wrong in your code.

Android: Ids of Markers of Google Maps

I have an app with TabHost and Google Maps. When I click on the tab that contains the Map, I do map.clear(). But this only cleans 7 markers. When I create the markers again, the id does not start from m0 but from m8.
How I can start the ids of the markers from 0?
thanks
You cannot control what ids will be generated by the API.
One thing you can do is to remove and recreate whole MapFragment or MapView, but that's an overkill.
Actually there is a trick to solve this .
//while plotting
int myId=0;
MarkerOptions markerOptions = new MarkerOptions()
.position("YOUR LATLNG VARIABLE")
.snippet(""+myId)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.orange_map01));
myId++;
//then in the marker click listener function.
gmap.setOnMarkerClickListener(new OnMarkerClickListener() {
#Override
public boolean onMarkerClick(final Marker arg0) {
// TODO Auto-generated method stub
System.out.println("The id you assigned will be available based on the click "+arg0.getSnippet());
//Do what ever you want to do with the assigned id , id will be created newly everytime.
Yourlist.get(arg0.getsnippet);
}
}

Android: chekbox in Google Maps mark and unmark markers

Is there any possibility to delete certain Google Map markers and having to do map.clear ()? Because in my app I have several checkbox marking and unmarked some markers ...
How can I achieve this?
I have done a similar thing in the past.
The trick is to maintain a list of the Marker objects, but within your own custom class (I have created a class called MapPoint which has the latlng, title, icon, snippet and holds a Marker).
Then when you want to push an update to the map you create a list of MapPoint objects (with the Marker set to null) with the current list of active MapPoint objects, remove duplicates and empty ones that no longer exist. This allows you to update the map as little as possible, rather than doing an entire refresh of everything.
Code snippet with comments for easier reading:
// holds the current list of MapPoint objects
public ArrayList<MapPoint> mCurrentPoints = new ArrayList<MapPoint>();
public void addMapPoints(ArrayList<MapPoint> mapPoints) {
// only process if we have an valid list
if (mapPoints.size() > 0) {
// iterate backwards as we may need to remove entries
for (int i = mCurrentPoints.size() - 1; i >= 0; i--) {
// get the MapPoint at this position
final MapPoint point = mCurrentPoints.get(i);
// check if this point exists in the new list
if (!mapPoints.contains(point)) {
// if it doesn't exist and has a marker (null check), remove
if (point.mMarker != null) {
// removes Marker from mMap
point.mMarker.remove();
}
// remove our MapPoint from the current list
mCurrentPoints.remove(i);
} else {
// already exists, remove from the new list
mapPoints.remove(point);
}
}
// add all the remaining new points to the current list
mCurrentPoints.addAll(mapPoints);
// go through every current point. If no mMarker, create one
for (MapPoint mapPoint : mCurrentPoints) {
if (mapPoint.mMarker == null) {
// create Marker object via mMap, save it to mapPoint
mapPoint.mMarker = mMap.addMarker(new MarkerOptions()
.position(mapPoint.getLatLng())
.title(mapPoint.getTitle())
.icon(mapPoint.getMarker())
.snippet(mapPoint.getInfoSnippetText()));
}
}
}
}
So you will want a method that determines what Marker objects are to be shown, create a MapPoint objects for them, then send the list of them to this addMapPoints() method.
A couple of good ideas: synchronize on the mCurrentPoints list (removed to make code snippet simpler) and ensuring you run on UI thread for the adding/removing markers. (Good idea to do this processing off the main thread then hop on to it for the actual adding/removing of Markers). And adapt to your own situation of course.
Use setVisible(true) on a Marker object (not a MarkerOptions, this is important). Add all the markers you want as visible/invisible, keep the references to the Marker objects, and toggle them on demand.

can i check before add new marker whether at this location other marker already added or not?

I work on google map .I add Markers first with type and then add marker again with distance so problem is there at some location two markers are add . so when i click on that it alternatively change. so i need to check marker is already there or not when add with distance.thanx.
I think your best way is to store already added markers to a collection, and then search for equal markers.
ArrayList<Marker> collection = new ArrayList()<Marker>;
collection.add(map.addMarker(Marker));
Something like this to add items, and then a function to check if exists
static boolean isMarkerOnArray(ArrayList<Marker> array, Marker m)
{
for(int c=0;c<array.size();c++)
{
Marker current = array.get(c);
if((current.getPosition().latitude == m.getPosition().latitude) &&(current.getPosition().longitude == m.getPosition().longitude) )
return true; //Both markers are equal
}
return false;
}
HandWrite code, it can be wrong, but i think thats the proper way to do it.
Hope this helps.

Differentiate between different markers in Maps API v2 (unique identifiers)

I have an ArrayList of a custom class. There are about 10 objects in the list, each with details like Title, Snippet, LatLng. I have successfully added all 10 to a Map by using my custom class functions like getTitle, getSnippet, getLatLng etc.
Now, when I click the info window (of the marker), I want to be able to somehow KNOW which object of my custom class does that marker correspond to.
For example, if I click the McDonald's market, I want to be able to know which item from my ArrayList did that marker belong to.
I've been looking at the MarkerOptions and there doesn't seem to be anything in there that I can use to identify the relevant custom object with.
If the question is too confusing, let me make it simple:
ArrayList<CustomObj> objects = blah
map.addMarker(new MarkerOptions().position(new LatLng(
Double.parseDouble(result.get(i).getCompanyLatLng()
.split(",")[0]), Double.parseDouble(result
.get(i).getCompanyLatLng().split(",")[1])))
.title(result.get(i).getCompanyName())
.snippet(result.get(i).getCompanyType())
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.pin)));
Now when this is clicked, I go on to the next page. The next page needs to know WHICH object was clicked so that I can send the other details to that page (e.g. Image URLs that need to be loaded etc).
How do I add a unique integer or any identifier to my marker?
One correct way is to use Map<Marker, CustomObj> which stores all markers:
Marker marker = map.addMarker(...);
map.put(marker, result.get(i));
and in onInfoWindowClick:
CustomObj obj = map.get(marker);
Another try is using Android Maps Extensions, which add getData and setData method to Marker, so you can assign your CustomObj object after creating marker and retrieve it in any callback.
I used the the snippet text for saving an unique ID. If you need the snippet it's will be for the popup and there you can just make your own (by finding the object from the ID) so you wont miss it but you'll certainly miss a unique ID for identifying the objects.
To find the right object I just iterate through them:
for(SomeObject anObject : someObjects) {
if(marker.getSnippet().equalsIgnoreCase(anObject.getID())) {
//you got at match
}
}
According to the discussion at the following link, Marker.equals and Marker.hashCode don't work sometimes. For example, when the map is panned or zoomed, or it's restarted/resumed.
Add Tag / Identifier to Markers
So Marker's ID is a better key than Marker itself for a HashMap.
Map<String, MyObject> markerMap = new HashMap<String, MyObject>();
Marker marker = map.addMarker(...);
MyObject myObject = new MyObject();
markerMap.put(marker.getId(), myObject);
I think using latitude and longitude, this could be done
map.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(final Marker marker) {
LatLng pos = marker.getPosition();
int arryListPosition = getArrayListPosition(pos);
return true;
}
});
and the method getArrayListPosition is
private int getArrayListPosition(LatLng pos) {
for (int i = 0; i < result.size(); i++) {
if (pos.latitude == result.get(i).getCompanyLatLng().split(",")[0]) {
if (pos.longitude == result.get(i).getCompanyLatLng()
.split(",")[1])
return i;
}
}
return 0;
}
This method will return you the position of your ArrayList who's Marker you have clicked. and you can get data from that position.
Hope it helps...
I am 4 years late to answer but I really amazed why no-one talked about marker.setTag and marker.getTag method.
As written in google API docs,
This is easier than storing a separate Map<Marker, Object>
They have introduce setTag and getTag to avoid use of Map<...>. You can use it as following way.
Marker marker = map.addMarker(...);
marker.setTag(result.get(i)); //Store your marker information here.
//To fetch your object...
map.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker) {
CustomObj obj = (CustomObj)marker.getTag();
//Your click handle event
// Pass the obj to another activity and you are done
return false;
}
});

Categories

Resources